Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Unity3D平滑相机移动和观看_C#_Unity3d_Camera - Fatal编程技术网

C# Unity3D平滑相机移动和观看

C# Unity3D平滑相机移动和观看,c#,unity3d,camera,C#,Unity3d,Camera,在我的Unity3D C#项目中被摄像机的移动卡住了 我所拥有的: 场景中的一些对象 相机,可以从任何物体的位置或其自身的当前位置飞行 我需要的是: 将摄影机平滑旋转到对象的一个原点 飞到物体附近的地点(有一个空的,所以我飞到空的坐标) 算法:旋转到对象的原点,旋转完成后,开始飞到空的位置。飞行时,观察物体的原点 问题是它不平滑,相机在运动结束时“跳跃” 我的C#代码(附在相机上): 使用系统集合; 使用System.Collections.Generic; 使用UnityEngine;

在我的Unity3D C#项目中被摄像机的移动卡住了

我所拥有的:

  • 场景中的一些对象
  • 相机,可以从任何物体的位置或其自身的当前位置飞行
我需要的是:

  • 将摄影机平滑旋转到对象的一个原点
  • 飞到物体附近的地点(有一个空的,所以我飞到空的坐标)
算法:旋转到对象的原点,旋转完成后,开始飞到空的位置。飞行时,观察物体的原点

问题是它不平滑,相机在运动结束时“跳跃”

我的C#代码(附在相机上):

使用系统集合;
使用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