将相机移向目标游戏对象并旋转

时间:2018-11-27 18:28:36

标签: c# unity3d

我在场景中有6个不同的按钮,有6个不同的空游戏对象。当我单击按钮1时,摄像头将移向游戏对象1并根据目标游戏对象旋转自身,但是当摄像头移向第三游戏对象时,我的摄像头将以不同的随机方式以及不同的随机旋转方式开始移动,这是由于浮点t = 0.0f;在代码中,例如当我调用public void Wallview()时,我的相机移向对象3,但它开始以随机旋转的不同随机方式移动,请帮助我

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class camMOVEtwo : MonoBehaviour {
    public Transform handleview;
    public Transform pressureview;
    public Transform wallview;
    public Transform sechandleview;
    public Transform pressuretwoview;
    public Transform switchview;
    public GameObject handlebtn;
    public GameObject pressurebtn;
    public GameObject wallbtn;
    public GameObject handletwobtn;
    public GameObject pressuretwobtn;
    public GameObject switchbtn;
    public float transitionSPEED;
    Transform currentVIEW;
    public bool flag = false;
    public bool isStarted = false;
    Vector3 currentangel;
    public List<GameObject> modelparts;

    private void Start () {
        handlebtn.SetActive (true);
        pressurebtn.SetActive (false);
        wallbtn.SetActive (false);
        handletwobtn.SetActive (false);
        pressuretwobtn.SetActive (false);
        switchbtn.SetActive (false);
        foreach (GameObject obj in modelparts) {
            obj.GetComponent<BoxCollider> ().enabled = false;
        }
    }

    private void Update () {
        if (flag && !isStarted) {
            StartCoroutine (newnew ());
            isStarted = true;
        }
    }

    IEnumerator newnew () {
        float t = 0.0f;
        while (t < 2.0f) {
            t += Time.deltaTime;
            transform.position = Vector3.Lerp (transform.position, currentVIEW.position, Time.deltaTime * transitionSPEED);
            currentangel = new Vector3 (Mathf.LerpAngle (transform.rotation.eulerAngles.x, currentVIEW.transform.rotation.eulerAngles.x, Time.deltaTime * transitionSPEED),
                Mathf.LerpAngle (transform.rotation.eulerAngles.y, currentVIEW.transform.rotation.eulerAngles.y, Time.deltaTime * transitionSPEED),
                Mathf.LerpAngle (transform.rotation.eulerAngles.z, currentVIEW.transform.rotation.eulerAngles.z, Time.deltaTime * transitionSPEED));
            transform.eulerAngles = currentangel;
            Debug.Log ("coroutine is running");
            yield return null;
        }
    }

    public void Handleview () {
        currentVIEW = handleview;
        handlebtn.SetActive (false);
        flag = true;
        isStarted = false;
    }

    public void Pressureview () {
        currentVIEW = pressureview;
        pressurebtn.SetActive (false);
        flag = true;
        isStarted = false;
    }

    public void Wallview () {
        currentVIEW = wallview;
        wallbtn.SetActive (false);
        flag = true;
        isStarted = false;
    }

    public void Secondhandleview () {
        currentVIEW = sechandleview;
        handletwobtn.SetActive (false);
        flag = true;
        isStarted = false;
    }

    public void Pressuretwoview () {
        currentVIEW = pressuretwoview;
        pressuretwobtn.SetActive (false);
        flag = true;
        isStarted = false;
    }

    public void Switchview () {
        currentVIEW = switchview;
        switchbtn.SetActive (false);
        flag = true;
        isStarted = false;
    }
}

2 个答案:

答案 0 :(得分:0)

大多数答案是重复。仍将其完全重写以供其他读者使用。

您可以采用points的数组,如以下脚本所示。 另外,为了保持相机的位置,我采用了变量currentPointIndex只是为了保持当前点的索引。

要正确旋转,请在协程内部使用Quaternion.RotateTowards();,如下面的代码所示

CameraMotion.cs

public Transform[] points;
public int currentPointIndex=0;
public Transform lookAtTarget;

private void Update()
{
    if (Input.GetKeyDown(KeyCode.Space))
    {
        StartCoroutine(CameraTransition(points[currentPointIndex],1.0f));
        currentPointIndex++;
    }
}

IEnumerator CameraTransition(Transform nextPoint,float time)
{
    float i = 0;
    float rate = 1 / time;

    Vector3 fromPos = transform.position;

    while (i<1)
    {
        i += Time.deltaTime * rate;
        transform.position = Vector3.Lerp(fromPos,nextPoint.position,i);


        Quaternion targetRotation = Quaternion.LookRotation(nextPoint.position-transform.position);
        transform.rotation = Quaternion.RotateTowards(transform.rotation,targetRotation,i);

        yield return 0;
    }
}}

基本上,我们在数组点上循环并相应地过渡。

或者,如果您的点不是线性形式(在数组中),则可以相应地修改逻辑。但是您可以使用相同的协同例程。

答案 1 :(得分:0)

我建议做些更好的事情,首先不要对事情进行硬编码,以允许它接受更多对象。第二,坚持使用更简单的解决方案。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LookAtObject : MonoBehaviour {

public float Speed = 0.001f;
private Transform _go;

// Update is called once per frame
void Update ()
{
    if (_go == null) return;

    Vector3 direction = _go.transform.position - transform.position;
    Quaternion toRotation = Quaternion.FromToRotation(transform.forward, direction);
    transform.rotation = Quaternion.Lerp(transform.rotation, toRotation, Speed * Time.time);
}

public void AdjustOrientation(Transform go)
{
    _go = go;
}
}


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class OnClick : MonoBehaviour
{
private LookAtObject _lookAt;


public void Start()
{
    _lookAt = FindObjectOfType<LookAtObject>();
}

public void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;

        if (Physics.Raycast(ray, out hit, 100))
        {
            //optionally if(hit.collider.tag != "MyTag") return;
            _lookAt.AdjustOrientation(hit.transform);
        }
    }
}
}

将这些类放置在相机上,发生的事情是第一类它通过您想要通过AdjustOrientation观察的对象所需要的东西。填充后,Update会查看该对象。

第二个类使您可以单击场景中包含刚体并且是运动学的任何对象。单击该对象后,它将设置AdjustOrientations,使照相机查看该对象,您可以轻松地向您的gameObject添加标签,并声明是否hit.collider.tag ==“ LookAt”然后允许其查看。