Unity:相机对撞机

时间:2017-01-19 12:56:51

标签: c# unity3d camera collision

我正在为一个学校项目创建一个第三人称游戏,但我遇到了一些碰撞问题:我有一个玩家带着相机作为孩子,有一个球体对撞机。当相机与房屋等任何景物碰撞时,应缩小。一旦它离开碰撞情况,它应该返回到它的旧位置(它的局部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

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

不确定我是否理解你想要达到的目的,但我会试一试:

我认为您应该调查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]属性来序列化私有变量(并因此使其显示在Inspector中)。我还添加了[Range()]属性,这在与设计师合作时非常有用(他们不喜欢原始数据;))