C# Unity3D平滑相机移动和观看
在我的Unity3D C#项目中被摄像机的移动卡住了 我所拥有的:C# Unity3D平滑相机移动和观看,c#,unity3d,camera,C#,Unity3d,Camera,在我的Unity3D C#项目中被摄像机的移动卡住了 我所拥有的: 场景中的一些对象 相机,可以从任何物体的位置或其自身的当前位置飞行 我需要的是: 将摄影机平滑旋转到对象的一个原点 飞到物体附近的地点(有一个空的,所以我飞到空的坐标) 算法:旋转到对象的原点,旋转完成后,开始飞到空的位置。飞行时,观察物体的原点 问题是它不平滑,相机在运动结束时“跳跃” 我的C#代码(附在相机上): 使用系统集合; 使用System.Collections.Generic; 使用UnityEngine;
- 场景中的一些对象
- 相机,可以从任何物体的位置或其自身的当前位置飞行
- 将摄影机平滑旋转到对象的一个原点
- 飞到物体附近的地点(有一个空的,所以我飞到空的坐标)
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
公共类testMove:monobhavior{
公共游戏对象startObj;
公共游戏对象endObj;
公共浮子速度=1.0F;
私人浮动开始时间;
专用浮动行程长度;
私有字符串名称;
私密的游戏对象;
无效开始(){
startTime=Time.Time;
如果(startObj){
}否则{
startObj=this.gameObject;
}
行程长度=矢量3.距离(startObj.transform.position,endObj.transform.position);
endObjName=endObj.name;
endObjLookAt=GameObject.Find(endObjName+“LookAt”);
}
无效更新(){
if(endObj){
float distCovered=(Time.Time-startTime)*速度;
浮动行程=距离覆盖/行程长度;
tweenLook(endObjLookAt,fractjourney);
浮动角度=四元数.angle(transform.rotation,Quaternion.LookRotation(endObjLookAt.transform.position-transform.position));
如果(角度因为你想要达到的目标意味着一个接一个的行动,我建议你使用协同程序:
public class testMove : MonoBehaviour
{
public Transform startObj;
public Transform endObj;
private Transform endObjLookAt;
public float rotationDuration;
public AnimationCurve rotationCurve;
public float movementDuration;
public AnimationCurve movementCurve;
private IEnumerator moveAndRotateCameraIEnumerator;
void Start()
{
// If you want to do it on start just call MoveAndRotateCamera() here, else call if from anywhere you want (a script, a game button, ...)
}
void Update()
{
if(Input.GetKeyDown(KeyCode.Space))
{
MoveAndRotateCamera();
}
}
public void MoveAndRotateCamera(Transform startTransform = null, Transform endTransform = null)
{
if(startTransform)
{
startObj = startTransform;
}
else
{
startObj = this.transform;
}
if(endTransform)
{
endObj = endTransform;
}
endObjLookAt = GameObject.Find(endObj.name + "LookAt").transform;
if(moveAndRotateCameraIEnumerator != null)
{
StopCoroutine(moveAndRotateCameraIEnumerator);
}
moveAndRotateCameraIEnumerator = MoveAndRotateCameraCoroutine();
StartCoroutine(moveAndRotateCameraIEnumerator);
}
private IEnumerator MoveAndRotateCameraCoroutine()
{
//ROTATION
Vector3 startEulerAngles = transform.eulerAngles;
transform.LookAt(endObjLookAt);
Vector3 deltaEulerAngles = new Vector3(Mathf.DeltaAngle(startEulerAngles.x, transform.eulerAngles.x), Mathf.DeltaAngle(startEulerAngles.y, transform.eulerAngles.y), Mathf.DeltaAngle(startEulerAngles.z, transform.eulerAngles.z));
Debug.Log("Starting rotation...");
float timer = 0.0f;
while(timer < rotationDuration)
{
timer += Time.deltaTime;
transform.eulerAngles = startEulerAngles + deltaEulerAngles * rotationCurve.Evaluate(timer / rotationDuration);
yield return new WaitForEndOfFrame();
}
transform.eulerAngles = startEulerAngles + deltaEulerAngles;
Debug.Log("Rotation done!");
//----
//MOVEMENT
Vector3 startPosition = transform.position;
Debug.Log("Starting movement...");
timer = 0.0f;
while(timer < movementDuration)
{
timer += Time.deltaTime;
transform.position = Vector3.Lerp(startPosition, endObj.position, movementCurve.Evaluate(timer / movementDuration));
transform.LookAt(endObjLookAt);
yield return new WaitForEndOfFrame();
}
transform.position = endObj.position;
transform.LookAt(endObjLookAt);
Debug.Log("Movement done!");
//----
}
}
公共类testMove:monobhavior
{
公共部门;
公共转型;
私有变换;注视;
公共浮动轮换持续时间;
公共动画曲线旋转曲线;
公众浮动时间;
公共动画曲线运动曲线;
私有IEnumerator移动和状态摄影机枚举器;
void Start()
{
//如果您想在开始时执行此操作,只需在此处调用MoveAndRotateCamera(),否则可以在任何位置(脚本、游戏按钮等)调用If
}
无效更新()
{
if(Input.GetKeyDown(KeyCode.Space))
{
移动摄像机();
}
}
公共无效移动状态摄影机(Transform startTransform=null,Transform endTransform=null)
{
if(启动转换)
{
startObj=startTransform;
}
其他的
{
startObj=this.transform;
}
如果(endTransform)
{
endObj=endTransform;
}
endObjLookAt=GameObject.Find(endObj.name+“LookAt”).transform;
if(moveAndRotateCameraireEnumerator!=null)
{
StopCorroutine(移动和状态摄影机枚举器);
}
MoveAndRotateComeraInumerator=MoveAndRotateComeraCoroutine();
Start例程(moveAndRotateCameraIEnumerator);
}
私有IEnumerator MoveAndRotateComeracorOutine()函数
{
//轮换
Vector3 StarteUrangles=transform.eulerAngles;
transform.LookAt(endObjLookAt);
Vector3 DeltaeUrangles=新矢量3(Mathf.DeltaAngles(starteureLangles.x,transform.eulerAngles.x),Mathf.DeltaAngles(starteureLangles.y,transform.eulerAngles.y),Mathf.DeltaAngles(starteureLangles.z,transform.eulerAngles.z));
Log(“开始旋转…”);
浮动定时器=0.0f;
while(计时器<旋转持续时间)
{
timer+=Time.deltaTime;
transform.eulerAngles=startEulerAngles+deltaEulerAngles*rotationCurve.Evaluate(计时器/旋转持续时间);
返回新的WaitForEndOfFrame();
}
transform.eulerAngles=星形三角形+三角形三角形;
Log(“旋转完成!”);
//----
//运动
Vector3起始位置=transform.position;
Log(“开始移动…”);
定时器=0.0f;
while(计时器<移动持续时间)
{
timer+=Time.deltaTime;
transform.position=Vector3.Lerp(startPosition、endObj.position、movementCurve.Evaluate(timer/movementDuration));
transform.LookAt(endObjLookAt);
返回新的WaitForEndOfFrame();
}
transform.position=endObj.position;
transform.LookAt(endObjLookAt);
Log(“移动完成!”);
//----
}
}
请注意以下几点:
- 将您的游戏对象变量更改为转换变量,因为您总是使用它们来访问转换组件,因此您可以直接使用它
- 为旋转和移动添加了时间概念,而不是速度概念(您也可以使用速度:只需将
time.deltaTime
乘以您的速度系数即可)
- 使用AnimationCurve可以调整旋转/移动的发生方式:只需在Inspector中设置曲线(曲线必须从(0,0)开始,并在(1,1)结束)
希望这能有所帮助,为什么不Lerp()
ing?@YotamSalmon您能礼貌地告诉我我应该使用什么参数以及在哪里使用Lerp吗?对不起,我对Unity非常陌生。只是尝试在Unity中移植我的ThreeJs相机运动。对不起,如果我看起来很粗鲁,这并不是我的初衷:)您传递了一个T首字母(可以是int、float、vector、Quaterion等),T final和lerping因子(0-1),它实际上是lerps移动。通常使用Time.deltaTime*N(N变化)作为lerpingfactor@YotamSalmonTh