Hey all, and thanks for reading this.
it must be late, and I will undoubtedly sleep on this and kick myself for being silly but, I cant clear out the 2am brain mush in my head to see the wood for the trees…
Please someone, help…
ive been trying to follow a really great idea of a tutorial based around hover physics, however the quality was initially shoddy until I realized he was kind enough to if uploaded a 720p version etc.
So, his tut was in Javascript, and I have done most of the converting, but…
My Problem is I want to cache the gameObject`s - transform.localRotation
but …
Im getting the evil error suggesting I cache the property value into a temporary/local variable, so i dunno, i just think I
m being stupid the more i write this now, cos this should be obvious really , i think.
I have tried caching to a temp type , but I`m doing something terribly wrong so help me “place deity of choice here”
Anyway, below is the code, hope someone can make sense out of it, let alone the above drivvle
Again, thanks for reading and helping in advance, any of those out there kind enough.
Gruffy
using UnityEngine;
using System.Collections;
public class HoverPhysics : MonoBehaviour
{
//civvy decs
public float forwardPower = 75000.0f;
public float steerPower = 35000.0f;
public float landingPower = 15.0f;
public float jumpingPower = 15.0f;
public float hoverHeight = 15.0f;
public float stability = 0.5f;
public float speedUpdate;
public GameObject go;
//
//
//privvy decs
private static HoverPhysics inst;
private Vector3[] hitNormal = new Vector3[5];
private Quaternion rotation;
private float increment;
private Vector3[] lastNormals = new Vector3[5];
private bool physicsSetup = false;
private Vector3 boxDimensions = new Vector3();
private Vector3[] cornerPoints = new Vector3[5];
private Transform[] corners = new Transform[5];
private BoxCollider boxCollider;
private float yBounce;
private Vector3 lastPosition;
private float distance;
private Vector3 average;
void Awake ()
{
inst = this;
//go = inst.gameObject;
//invoke Physics initialisations
InitPhysics();
}
//Update is called once per frame
void Update ()
{
//calculate the speed
CalcSpeed();
}
//as we are utilising a physics calculation
//it seems best to apply this in a FixedUpdate(0 Method as opposed to the usual Update() method;
void FixedUpdate()
{
if(physicsSetup)
{
RaycastHit hit;
for(int i = 0; i <= corners.Length -1; i++)
{
if(Physics.Raycast(corners[i].position, -corners[i].up, out hit, hoverHeight + 100))
{
//
hitNormal[i] = go.transform.InverseTransformDirection(hit.normal);
if(lastNormals[i] != hitNormal[i])
{
increment = 0;
lastNormals[i] = hitNormal[i];
}
distance = hit.distance;
if(hit.distance < hoverHeight)
{
//bring it down
constantForce.relativeForce = (-average + inst.transform.up) * rigidbody.mass * jumpingPower * rigidbody.drag * Mathf.Min(hoverHeight, hoverHeight / distance);
}
//raise it up
else
{
constantForce.relativeForce = -(inst.transform.up) * rigidbody.mass * landingPower * rigidbody.drag * Mathf.Min(hoverHeight, hoverHeight / distance);
}
//this conditional results in a bounce effect as a by product of the revolving calculation to establish if
//you have dropped
}
else
{
constantForce.relativeForce = -(inst.transform.up) * rigidbody.mass * jumpingPower * rigidbody.drag * 6 *(1-Input.GetAxis("Vertical"));
}
}
//to attain the average of all they must be added together and divided by 2 (2 was found best through trial and err,
//but could be changed).
//find the vector normal and store it in Vector3 average
average = -(hitNormal[0] + hitNormal[1] + hitNormal[2] + hitNormal[3] + hitNormal[4])/ 2;
if(increment != 1)
{
increment += 0.03f;
}
inst.rotation = Quaternion.Slerp(go.transform.localRotation, Quaternion.Euler (average * Mathf.Rad2Deg), increment);
go.transform.localRotation = rotation;
//I GOT A PROBLEM HERE - I NEED TO CACHE THE TRANSFORM.LOCALROTATION, BUT ALREADY HAVE IT //AVAILABLE I THINK, BUT SOMEHOW CANNOT ACCESS IT?.
//MAYBE ITS OUT OF SCOPE, BUT I THOUGHT IT WAS AVAILABLE TO THE WHOLE CLASS ETC
//IT MIGHT BE THAT ITS 02;18 IN THE MORNING THOUGH, NUNIGHT SLEEP OL` ME
//I`LL GET YEE IN THA MORROW HA HA A HOO HAR HAR HAR ! :(
//float temp = go.transform.localRotation.y;
//temp = transform.up.y * Mathf.Deg2Rad;
go.transform.localRotation.y = inst.transform.up.y * Mathf.Deg2Rad;
//go.transform.localRotation.y = temp;
float fwdForce = Input.GetAxis ("Vertical") * forwardPower;
rigidbody.AddForce(inst.transform.forward * fwdForce);
float steerForce = Input.GetAxis ("Horizontal") * steerPower;
rigidbody.AddTorque(inst.transform.up * steerForce);
} //end physics setup conditional
}//end fixed update
//draw the spheres to cast ray from in the editor for debugage using predefined method provided by unity - word!
void OnDrawGizmos()
{
if(corners[0] != null){Gizmos.DrawWireSphere(corners[0].position, 1.0f);}
if(corners[1] != null){Gizmos.DrawWireSphere(corners[1].position, 1.0f);}
if(corners[2] != null){Gizmos.DrawWireSphere(corners[2].position, 1.0f);}
if(corners[3] != null){Gizmos.DrawWireSphere(corners[3].position, 1.0f);}
if(corners[4] != null){Gizmos.DrawWireSphere(corners[4].position, 1.0f);}
}
//calcluate the speed
void CalcSpeed()
{
if(lastPosition != inst.transform.position)
{
//cache the distance using Distcane function
float distance = Vector3.Distance(inst.transform.position, lastPosition);
speedUpdate = (distance/1000.0f) / (Time.deltaTime / 3600.0f); // making it KM/H
}
}
//method used to initialise all the physics related objects and establish their initial positions and forces
void InitPhysics()
{
//this would return an object that can be casted to BoxCollider
//boxCollider = go.AddComponent("BoxCollider");
//the below returns an actual boxcollider
boxCollider = go.AddComponent<BoxCollider>();
//it is essential to multiply each dimension (x, y ,z) with the local scale becaause we are calculating the child and not the parent,
//so the transform has to be relative to the parents world , NOT the game world coords
boxDimensions = new Vector3(boxCollider.size.x * go.transform.localScale.x, boxCollider.size.y * go.transform.localScale.y, boxCollider.size.z * go.transform.localScale.z ) * stability;
//calculate the positions from the dimensions and set a vector3 on the corners of the box at each point
cornerPoints[0] = Vector3 (inst.transform.position.x - boxDimensions.x /2, inst.tranform.position.y - boxDimensions.y /2, inst.tranform.position.z + boxDimensions.z /2);
cornerPoints[1] = Vector3 ((boxDimensions.x /2) + (inst.transform.position.x - boxDimensions.x /2), inst.tranform.position.y - boxDimensions.y /2, inst.tranform.position.z + boxDimensions.z /2);
cornerPoints[2] = Vector3 ((boxDimensions.x /2) + (inst.transform.position.x - boxDimensions.x /2), inst.tranform.position.y - boxDimensions.y /2, inst.tranform.position.z - boxDimensions.z /2);
cornerPoints[3] = Vector3 (inst.transform.position.x - boxDimensions.x /2, inst.tranform.position.y - boxDimensions.y /2, inst.tranform.position.z - boxDimensions.z /2);
cornerPoints[4] = Vector3 (inst.transform.position);
//destroy collider because we no longer need it, as we already have the dimensions
Destroy (boxCollider);
//as the coords will now be outdated , here we define a loop to place down the spheres that represent the corners points
//of the box being used to draw data for the physics calculation
for(int i = 0; i < cornerPoints.Length -1; i++)
{
GameObject stabilizer = new GameObject.CreatePrimitive(PrimitiveType.Sphere);
//stabilizer.transform.position = go.transform.position;
//name it based on array position
stabilizer.name = "Stabilizer" + "(" + i + ")";
//assign its parent transform
stabilizer.transform.parent = go.transform;
//stabilizer.transform.position = go.transform.position;
stabilizer.transform.localPosition = inst.transform.InverseTransformPoint(cornerPoints[i]);
corners[i] = stabilizer.transform;
Destroy (stabilizer.GetComponent("MeshRenderer"));
Destroy (stabilizer.GetComponent("Collider"));
}
//reduce memory footprint as we non longer need the following cached anymore
//clear out corner points array ready for next set
cornerPoints = null;
//reset physicsSetup bool
physicsSetup = true;
}
}