我目前对我制作的脚本有一点问题。基本上,我想创建一个脚本,使其游戏对象(我们将其命名为 A)并遵循另一个游戏对象(命名为 B)的位置。我知道一个简单的方法是将 A 到 B 的父级,但我没有这样做有两个原因:1)我希望能够对 A 的运动应用平滑(我可以改变其值);2) 我希望能够让 A 随心所欲地跟随 B 的位置和/或旋转。
这是我写的脚本:
using UnityEngine;
using System.Collections;
public class FollowGameObject : MonoBehaviour {
public GameObject m_GameObjectToFollow;
public bool m_FollowPosition;
public bool m_FollowRotation;
public float m_PositionSmoothing;
public float m_RotationSmoothing;
// Should not be changed once set
public bool m_UseOffsetPosition;
public bool m_UseOffsetRotation;
private Vector3 m_PositionOffset;
private Quaternion m_RotationOffset;
void Start () {
m_PositionSmoothing = Mathf.Clamp(m_PositionSmoothing, 0.0f, 1.0f);
m_RotationSmoothing = Mathf.Clamp(m_RotationSmoothing, 0.0f, 1.0f);
if (m_UseOffsetPosition)
{
m_PositionOffset = transform.position - m_GameObjectToFollow.transform.position;
} else {
m_PositionOffset = Vector3.zero;
}
if (m_UseOffsetRotation)
{
m_RotationOffset = transform.rotation * Quaternion.Inverse(m_GameObjectToFollow.transform.rotation);
} else {
m_RotationOffset = Quaternion.identity;
}
}
void FixedUpdate () {
if (m_FollowPosition) {
Vector3 goalPosition = m_GameObjectToFollow.transform.position + m_PositionOffset;
transform.position = Vector3.Lerp(transform.position, goalPosition, m_PositionSmoothing);
//transform.Translate(newPosition - transform.position, Space.World);
}
if (m_FollowRotation) {
Quaternion goalRotation = m_GameObjectToFollow.transform.rotation * m_RotationOffset;
transform.rotation = Quaternion.Lerp(transform.rotation, goalRotation, m_RotationSmoothing);
}
}
我希望代码易于理解,如果不能随意询问。无论如何,一旦我将此脚本附加到 A 并将其m_GameObjectToFollow
属性分配给 B(B 是角色控制器的父级,并且我将球体渲染器作为 A 的父级,因此我可以查看它是否正确遵循 B),我注意到 A 是确实跟随 B,但我看到它的位置(通过球体渲染器)在“正确”位置(B)和另一个位置之间“波动”。从视觉上看,球体在闪烁。我尝试将平滑值设置为 1(即 A 应始终位于 B 的位置/旋转)。我仍然看到闪烁。
有人可以向我解释我做错了什么吗?
编辑:似乎我使用 Lerp 的最后一个值是错误的。我修改了脚本以使用速度值而不是平滑值,但当我尝试创建一些平滑运动(速度值较低)时仍然存在同样的问题。我无法正确解释问题。了解问题的最佳方式是亲自体验: 1) 创建一个包含地形和角色控制器的场景;2)将主摄像机作为控制器的父级(以便它始终跟随它);3) 使用渲染器(例如球体)创建一个新的游戏对象,而不是任何其他游戏对象的父级,但将以下脚本附加到它:
using UnityEngine;
使用 System.Collections;
公共类 FollowGameObject:MonoBehaviour {
public GameObject m_GameObjectToFollow;
public bool m_FollowPosition;
public bool m_FollowRotation;
// Betzeen 0 and 1. 1 means that a complete unsmoothed follow
public float m_PositionFollowSpeed;
public float m_RotationFollowSpeed;
// Should not be changed once set
public bool m_UseOffsetPosition;
public bool m_UseOffsetRotation;
private Vector3 m_PositionOffset;
private Quaternion m_RotationOffset;
void Start () {
if (m_UseOffsetPosition)
{
m_PositionOffset = transform.position - m_GameObjectToFollow.transform.position;
} else {
m_PositionOffset = Vector3.zero;
}
if (m_UseOffsetRotation)
{
m_RotationOffset = transform.rotation * Quaternion.Inverse(m_GameObjectToFollow.transform.rotation);
} else {
m_RotationOffset = Quaternion.identity;
}
}
void Update () {
if (m_FollowPosition) {
Vector3 goalPosition = m_GameObjectToFollow.transform.position + m_PositionOffset;
transform.position = Vector3.Slerp(transform.position, goalPosition, Time.deltaTime * m_PositionFollowSpeed);
}
if (m_FollowRotation) {
Quaternion goalRotation = m_GameObjectToFollow.transform.rotation * m_RotationOffset;
transform.rotation = Quaternion.Slerp(transform.rotation, goalRotation, Time.deltaTime * m_RotationFollowSpeed);
}
}
}
其中:m_GameObjectToFollow = 角色控制器 GameObject;
m_FollowPosition = 真;
m_PositionFollowSpeed = 10;
(其他参数值对本次测试无关紧要)
现在开始场景并移动角色控制器,我会看到球体在运动过程中闪烁,但如果你停止移动,它会顺利转到控制器。