I’m new to c# scripting but I managed to write a script that smoothly moves a camera from one defined target position and rotation to another, but it was bulky with a coroutine for each target.
I figured that I should be able to concatenate (is that the correct word?) a string to help define the name of the Vector3 to be called - see lines 18 & 25 in the example - but it throws the “Cannot implicitly convert type ‘string’ to 'UnityEngine.Vector3” error at me.
Hopefully someone will be able to help me sort it out.
Thanks in advance,
Mat
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class moveCamRefined : MonoBehaviour
{
public GameObject objectToMove;
public float moveDuration = 1;
public GameObject target1;
public GameObject target2;
private Vector3 targetPosition;
private int key;
void Update()
{
if (Input.GetKeyDown("1"))
{
print("the one was pressed");
key = 1;
targetPosition = "target" + key + ".transform.Position";
StartCoroutine(moveObject(targetPosition, moveDuration));
}
if (Input.GetKeyDown("2"))
{
print("the two was pressed");
key = 2;
targetPosition = "target" + key + ".transform.Position";
StartCoroutine(moveObject(targetPosition, moveDuration));
}
}
//COROUTINE
//move to targetPosition
IEnumerator moveObject(Vector3 targetPosition, float moveDuration)
{
float time = 0;
Vector3 startPosition = objectToMove.transform.position;
while (time < moveDuration)
{
objectToMove.transform.position = Vector3.Lerp(startPosition, targetPosition, time / moveDuration);
objectToMove.transform.rotation = Quaternion.Slerp(objectToMove.transform.rotation, target1.transform.rotation, time / moveDuration);
time += Time.deltaTime;
yield return null;
}
objectToMove.transform.position = (targetPosition);
}
}
What do you mean by ‘The name of the Vector3 to be called’?
The reason you’re getting the error is because you’re trying to put a String-value (text) into a Vector3-object (3 floats), which isn’t possible. The value you’re placing into targetPosition should be a Vector3, not a Position.
Are you trying to set targetPosition to either target1.position or target2.position?
If so, try something like this:
private GameObject[] targets = new GameObject[] {target1, target2};
if (Input.GetKeyDown("1")) // You should really use KeyCodes instead of a string here
{
targetPosition = targets[0].transform.position;
}
if (Input.GetKeyDown("2"))
{
targetPosition = targets[1].transform.position;
}
It looks like you were trying to perform reflection: using runtime data to access members (amongst other things).
This is absolutely possible! It’s also a bad idea:
Reflection is slow. The compiler doesn’t know what you’re going to do ahead of time, so it can’t emit efficient code.
Reflection is unsafe. The compiler can’t prove much about your runtime data, so it can’t check if you are using a valid name.
Reflection is annoying to write. You lose a lot of conveniences, like accurate code completions and renaming.
(it also doesn’t look much like what you’ve written – this is just the idea )
Of course, it’s very reasonable to want to associate names with values. For that, you should use a data structure – maybe an array, like shown above, maybe a List if you want to be able to resize it at runtime, or maybe a Dictionary if you want to use arbitrary keys, rather than just sequential numbers.
My main reason for doing this is to develop an understanding of scripting in Unity, I’lll definitely be looking into Cinemachine in the near future though.