I have a movement script, which takes in a GameObject (to move), a Goal Transform (to travel to) and a Float speed (rate to move towards destination). It adds the variables to unique lists, and in the Update function it moves the GameObject step by step towards to goal location. Here is the code for how this works:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour {
public GameObject[] cardPosons;
private static GameObject[] cardPosns;
//each script can choose speed. Most(if not all) will pull this value.
public static float cardSpeed = 2;
private static List<GameObject> movingCards = new List<GameObject>();
private static List<float> movingCardSpeed = new List<float>();
private static List<Vector3> movingCardGoalPosition = new List<Vector3>();
private static List<Quaternion> movingCardGoalRotation = new List<Quaternion>();
private static float speedMultiplier = 0.1f;
void Start() {
cardPosns = cardPosons;
}
void Update() {
StepMovement();
}
public static void MoveCard(GameObject card, int goal, float speed) {
Transform cardStartPosition = card.transform;
Transform goalLocation = cardPosns[goal].transform;
float posOfset = card.GetComponent<Card>().CardHeightOffset();
Vector3 ofsetPosition = new Vector3(goalLocation.position.x, goalLocation.position.y + +posOfset, goalLocation.position.z);
if (speed == 0) {
card.transform.position = ofsetPosition;
card.transform.rotation = goalLocation.rotation;
}
else {
movingCards.Add(card);
movingCardSpeed.Add(speed);
movingCardGoalPosition.Add(ofsetPosition);
movingCardGoalRotation.Add(card.transform.rotation);
}
}
private static void StepMovement() {
int counter = -1;
for (int i = 0; i < movingCards.Count; i++) {
counter++;
Transform currentTransform = movingCards[counter].transform;
float movSpeed = movingCardSpeed[counter] * speedMultiplier;
Vector3 remainingDistance = movingCardGoalPosition[counter] - movingCards[counter].transform.position;
// Individualize remainingDistance's floats, turn all positive.
float remX = remainingDistance.x; if (remX < 0) { remX = -remX; }
float remY = remainingDistance.y; if (remY < 0) { remY = -remY; }
float remZ = remainingDistance.z; if (remZ < 0) { remZ = -remZ; }
// Work out which float is the largest.
float maxAxisLength = 0;
if (remX >= remY && remX >= remZ) { maxAxisLength = remX; }
if (remY >= remX && remY >= remZ) { maxAxisLength = remY; }
if (remZ >= remX && remZ >= remY) { maxAxisLength = remZ; }
//Limit Movement distance to not overshoot largest target.
if (movSpeed > maxAxisLength) { movSpeed = maxAxisLength; }
// Use new movSpeed to find deltaX, deltaY and deltaZ respectively.
float xResult = movSpeed * (remainingDistance.x / maxAxisLength);
float yResult = movSpeed * (remainingDistance.y / maxAxisLength);
float zResult = movSpeed * (remainingDistance.z / maxAxisLength);
// Set new position based on 3 deltaValues.
currentTransform.position += new Vector3(xResult, yResult, zResult);
if (currentTransform.position == movingCardGoalPosition[counter]) {
// On arrival at destination, respective variables are removed from their Lists.
movingCards.Remove(movingCards[counter]);
movingCardSpeed.Remove(movingCardSpeed[counter]);
movingCardGoalPosition.Remove(movingCardGoalPosition[counter]);
movingCardGoalRotation.Remove(movingCardGoalRotation[counter]);
}
}
}
}
I’ve hit a problem trying to replicate this for rotation. I am trying to make it work so that no matter what 2 rotations I insert (be they just on 1 axis or in all 3), it will still successfully transition between the 2 Quaternions. Here is the code I attempted to use (inserted into the previous script, lines 73-74):
Quaternion goalRotation = movingCardGoalRotation[counter];
Quaternion currentRotation = currentTransform.rotation;
float maxAxisRotation = 0;
float rotX = currentRotation.x; if (rotX < 0) { rotX = -rotX; }
float rotY = currentRotation.y; if (rotY < 0) { rotY = -rotY; }
float rotZ = currentRotation.z; if (rotZ < 0) { rotZ = -rotZ; }
float rotW = currentRotation.w; if (rotW < 0) { rotW = -rotW; }
if (rotX >= rotY && rotX >= rotZ && rotX >= rotW) { maxAxisRotation = rotX; }
if (rotY >= rotX && rotY >= rotZ && rotY >= rotW) { maxAxisRotation = rotY; }
if (rotZ >= rotX && rotZ >= rotY && rotZ >= rotW) { maxAxisRotation = rotZ; }
if (rotW >= rotX && rotW >= rotY && rotW >= rotZ) { maxAxisRotation = rotW; }
float rotSpeed = movingCardSpeed[counter] * 5;
if (rotSpeed > maxAxisRotation) { movSpeed = maxAxisRotation; }
float xRotResult = rotSpeed * (currentRotation.x / maxAxisRotation);
float yRotResult = rotSpeed * (currentRotation.y / maxAxisRotation);
float zRotResult = rotSpeed * (currentRotation.z / maxAxisRotation);
float wRotResult = rotSpeed * (currentRotation.w / maxAxisRotation);
currentTransform.rotation += new Quaternion(xRotResult, yRotResult, zRotResult, wRotResult);
Fairly unsurprisingly, Quaternion (as a method) kicked off, not allowing the modification += to add 2 Quaternions together. You cannot add 2 Quaternions together either (i.e. Quaternion abc = Quat1 + Quat2 ).
Can anyone help me find a way to rotate an object steadily between 2 locations (I have the transform for the current object, a transform for the resultant rotation aim, and a uniform speed that the object is approaching it’s transform destination).