- Home /
Quaternions, lateral transform (and interp) on a surface that rotates in X and Z
Ok so I've been learning Unity for six weeks (no prior knowledge of programming) for my university course, and I'm simply confounded by Quaternions. I have to use C# for this, and I've already read everything else I can find about Quaternions. = I'm making a tilting board game similar to Labyrinth, and I need to attach a sliding object onto the surface of this board to make a door so that no matter where the surface is in 3D space, the object still slides a given number of units in a relative direction as though the surface were flat. Most of the examples I can find only show examples of how to move things on a static surface and are thus of no use to me.
The following script has the objects which make up the door sliding correctly relative to each other, but they are in no way connected to the board (and believe me, I've tried, and tried, and tried with no success). The current script has the movement being processed as a Vector3, but I need to convert it so that it acquires angular corrections based off the board that it is parented to. I've been stuck on this infuriating problem for two days and I really can't afford to waste any more time, can anybody please help me?
I'll be watching this for a reply so if you need any other information in order to provide an answer please ask.
using UnityEngine; using System.Collections;
public class CylinderDoor : MonoBehaviour { public GameObject DoorA; public GameObject DoorB; public GameObject DoorC;
public float slow = 10.0F;
public float fast = 20.0F;
public float durationA = 5.0F;
public float durationB = 3.75F;
public float durationC = 2.5F;
private float startTime;
void Start()
{
startTime = Time.time;
}
void Update()
{
float tA = (Time.time - startTime) / durationA;
float tB = (Time.time - startTime) / durationB;
float tC = (Time.time - startTime) / durationC;
DoorA.transform.position = new Vector3(Mathf.SmoothStep(slow, fast, tA), 0, 0);
DoorB.transform.position = new Vector3(Mathf.SmoothStep(slow, fast, tB), 0, 0);
DoorC.transform.position = new Vector3(Mathf.SmoothStep(slow, fast, tC), 0, 0);
}
}
I have another similar problem with an object that is supposed to interpolate smoothly between two points, but again I am scratching my head about how I attach the movement to a surface which is itself already moving.. so far I have this: Game Object A and B are empty objects that I thought I could use to determine the two points to move between, but their Quaternion adjustments obviously aren't being added to the X, Y, Z inputs I give it because I don't know how.
using UnityEngine; using System.Collections;
public class BumpSection1 : MonoBehaviour { public GameObject A; public GameObject B;
IEnumerator Start ()
{
Vector3 pointA = A.transform.position;
Vector3 pointB = B.transform.position;
while (true)
{
yield return StartCoroutine(MoveObject(transform, pointA, pointB, 1.0f));
yield return StartCoroutine(MoveObject(transform, pointB, pointA, 1.0f));
}
}
IEnumerator MoveObject (Transform thisTransform, Vector3 startPos, Vector3 endPos, float time)
{
float i = 0.0f;
float rate = 1.0f / time;
while (i < 1.0f)
{
i += Time.deltaTime * rate;
thisTransform.position = Vector3.Lerp(startPos, endPos, i);
yield return null;
}
}
}
Just out of a sense of completeness, this is the script for the tilting board (which was given to us by the lecturer at the beginning so that we had somewhere to go from, and while I can sort of understand what I'm reading, I don't know how to call on it in other scripts (which is probably obvious by now); any help would be very much appreciated.
using UnityEngine; using System.Collections;
public class Tilt : MonoBehaviour { float smooth = 1.9f; float tiltAngle = 25.0f;
void Update ()
{
float tiltAroundX = Input.GetAxis ("Horizontal") * tiltAngle;
float tiltAroundZ = Input.GetAxis ("Vertical") * tiltAngle;
Quaternion target = Quaternion.Euler(tiltAroundX, 0, tiltAroundZ);
transform.rotation = Quaternion.Slerp (transform.rotation, target, Time.deltaTime * smooth);
}
}
Let me restate what I think you are asking. You have a tilting surface. A block is to rest on this surface. Commands send the block sliding along the surface smoothly over time. The surface can be tilted, but that tilt should be ignored by the block other than to remain on that surface. Finally you are making all of these changes using transforms rather than the physics engine.
The easiest solution is to make the block a child of the surface. Then you can either use transform.Translate() to move the block or you can use transform.localPosition to move the block. As a child the block will track the parent (surface).
Thank you very much, Yeah I just tested those and while they seem to work I'm still stuck with a block that leaps from pointA to pointB, or a block that moves in one direction forever. I'm sure I could start figuring how to make triggers that tell the block to reverse direction or whatever, but surely there is a dead simple way of making a block that simply slides smoothly from A to B and back again without all this confusion. Forgive me for being such a noob, I learn better with cannibalization than by working with a blank sheet...