我正在为一个学校项目创建一个第三人称游戏,但我遇到了一些碰撞问题:我有一个玩家带着相机作为孩子,有一个球体对撞机。当相机与房屋等任何景物碰撞时,应缩小。一旦它离开碰撞情况,它应该返回到它的旧位置(它的局部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
答案 0 :(得分:1)
您需要检查哪个碰撞器与相机碰撞器发生碰撞,您可以使用OnColliderEnter(Collider other)
中的类似结构实现此目的:
Collider playerCollider = GameObject.Fine("Player").GetComponent<Collider>();
if (!other == playerCollider)
{
//Do your zooming out.
}
答案 1 :(得分:0)
不确定我是否理解你想要达到的目的,但我会试一试:
我认为您应该调查OnTriggerEnter
和OnTriggerExit
事件,这样您就可以告诉相机在输入触发器时移开,并在退出时退回。
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)
}
还有两件事:
[SerializeField]
属性来序列化私有变量(并因此使其显示在Inspector中)。我还添加了[Range()]属性,这在与设计师合作时非常有用(他们不喜欢原始数据;))