【问题标题】:Unity: Camera ColliderUnity:相机对撞机
【发布时间】:2017-01-19 12:56:51
【问题描述】:

我正在为一个学校项目创建一个第三人称游戏,但我遇到了一些碰撞问题:我有一个带相机的玩家小时候有一个球体碰撞器。当相机与房屋等任何风景物体发生碰撞时,它应该缩小。一旦它离开碰撞情况,它应该回到原来的位置(它的局部 y 应该是 4.5)。现在我在静止不动时遇到以下问题:相机不断离开并进入对象的对撞机,导致它不断放大和缩小。这会导致看起来非常有问题的相机移动。有什么办法可以解决这个问题吗?

我使用了以下代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;



public class CamMovement : MonoBehaviour
 {
     public GameObject Parent;

     //Checks if the camera collides with something
     void OnTriggerStay(Collider other)
     {
         //When colliding, the camera moves up and back from the player object          
         transform.position += new Vector3(0, 0.2f, -0.2f);    
     }


     void Update()
     {
         //makes sure the camera always looks at the player object   
         transform.LookAt(Parent.transform);

         //Moves the camera back to the normal (local) position
         if (transform.localPosition.y > 4.5f)
         {
             transform.position += new Vector3(0, Time.deltaTime * -4f, Time.deltaTime * 4f);
         }
     }
 }

相机与某物碰撞时的样子:http://imgur.com/a/7ot9R

【问题讨论】:

  • 您可以在播放器对象上放置一个标签,然后获取它的相机对撞机并执行if(!other == playerCollider){zoomOut();} 如果这解决了您的问题,请告诉我,我会写下它作为正确的答案。
  • 如果任何答案解决了您的问题,请考虑接受它作为正确的答案。 (接受答案有助于未来访问此页面的访问者)

标签: c# unity3d camera collision


【解决方案1】:

您需要检查哪个对撞机与相机对撞机发生碰撞,您可以使用OnColliderEnter(Collider other) 中类似的结构来实现这一点:

Collider playerCollider = GameObject.Fine("Player").GetComponent<Collider>();
if (!other == playerCollider)
{
//Do your zooming out.
}

【讨论】:

    【解决方案2】:

    不确定我是否正确理解您想要实现的目标,但我会试一试:

    我认为您应该研究OnTriggerEnterOnTriggerExit 事件,这样您就可以告诉相机在输入触发器时移开并在其退出时移回。

    public class CamMovement : MonoBehaviour
    {
        //using "parent" as variable name is not recommended since Transform class already contains a parent variable
        [SerializeField]
        private GameObject parentToLookAt;
        [SerializeField]
        private Vector3 localPositionOffset;
        [Range(0.0f, 10.0f)]
        [SerializeField]
        private float transitionSpeed;
    
        private Vector3 localPositionOnStart;
        private bool applyOffset;
    
        void Start()
        {
            localPositionOnStart = transform.localPosition;
            applyOffset = false;
        }
    
        void Update()
        {
            //Makes sure the camera always looks at the player object
            //You can also use: transform.LookAt(transform.parent); 
            transform.LookAt(parentToLookAt.transform);
    
            //Moves the camera to the right local position (note that using Mathf.Lerp is not optimal performance-wise but if you want more info on this
            //I recommend looking for further informations at https://chicounity3d.wordpress.com/2014/05/23/how-to-lerp-like-a-pro/ )
            if (applyOffset)
            {
                transform.localPosition = Mathf.Lerp(transform.localPosition, localPositionOnStart + localPositionOffset, transitionSpeed * Time.deltaTime);
            }
            else
            {
                transform.localPosition = Mathf.Lerp(transform.localPosition, localPositionOnStart, transitionSpeed * Time.deltaTime);
            }
        }
    
        //Checks if the camera collides with something
        void OnTriggerEnter(Collider other)
        {
            applyOffset = true;
        }
    
        //Checks if the camera stops colliding with something
        void OnTriggerExit(Collider other)
        {
            applyOffset = false;
        }
    
        //You can also use this:
        //void OnTriggerStay(Collider other)
        //{
        //    applyOffset = true;
        //}
        // and set applyOffset to false at the end of the Update() method (OnTrigger events are called before Update each frame)
    }
    

    还有两件事:

    • 在 C# 中编程时,一个常见的规则是不使用大写字母来开始变量名(这是保留给类名的):您可以查看here 以获取全局指南
    • 您也可以使用[SerializeField] 属性来序列化私有变量(并因此使其出现在检查器中)。我还添加了 [Range()] 属性,这在与设计师合作时很有用(他们不喜欢原始数字;))

    【讨论】:

    • 我可能是错的,但我认为你误解了这个问题。
    • @JamesHughes 是的,我不确定:我不知道问题是否与 Collider 与任何东西碰撞有关(这需要像您在回答中所做的那样进行快速测试(并且即使在我的:在这种情况下,应始终进行测试以避免任何不必要的碰撞))。或者也许只是当相机远离玩家时相机碰撞器不再碰撞所以它开始向后移动,然后不停地来回移动(无法真正了解层次结构是如何组织的从问题...)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多