0
votes

i have six different empty game objects in the scene with 6 different buttons. When i click on button 1 the camera will move towards game object 1 and rotate itself according to the target game object but when camera moves towards 3rd game object my camera will start moving in a different random way along with different random rotation this is caused by float t = 0.0f; in the code like when i call public void Wallview() then my camera moves towards object 3 but it starts moving in different random way with random rotation please help me thank

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

2 Answers

0
votes

Most of the answer is a repetition. Still Rewriting it completely for others readers context.

You can take an array of points as shown in the below script. Also To maintain where the camera is I have taken the variable currentPointIndex just to maintain the index of the current point.

For proper rotation use Quaternion.RotateTowards(); inside the coroutine as shown in the code below

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;
    }
}}

Basically, we are looping over the array points and transitioning accordingly.

Alternatively, If your points are not in a linear form (in an array) you can modify the logic accordingly. But you can use the same Co-routine.

0
votes

I suggest making things a bit better, first don't make things hardcoded allow it to accept more objects.. Second stick with a simpler solution.

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);
        }
    }
}
}

Place these classes on your camera, what happens is a few things first class it takes in a object you want to look at through AdjustOrientation. Update will look at that object once its populated.

Second class allows you to click any object in the scene that contains a rigidbody and is Kinematic. Once the object is clicked it will set the AdjustOrientations making the camera look at that object you can easily add a tag to your gameObject and state if hit.collider.tag == "LookAt" then allow it to look.