Created
February 27, 2013 02:37
-
-
Save SteveSwink/5044505 to your computer and use it in GitHub Desktop.
Scaleable object script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
using System.Collections.Generic; | |
public class ScaleableObject : MonoBehaviour { | |
[ExecuteInEditMode] | |
public TextMesh juiceReadoutObject; | |
public int minJuice = 1; | |
public int maxJuice = 500; | |
public GameObject mesh; | |
public float CCradius, CCheight, CCoffset; | |
public float scaleSpeed = 1.05f; | |
public int juiceAtRuntime; | |
// [HideInInspector] | |
public int myCurrentJuice, min, max; | |
bool hasScaleableChild; | |
ScaleableObject[] myChildren; | |
Vector3 startPos, startScale, myCurrentScale; | |
int startJuice; | |
Quaternion startRot; | |
float scaleFactor = 4.0f; | |
bool scalingFromGun; | |
List<Collider> collidersToIgnore = new List<Collider>(); | |
List<GameObject> clones = new List<GameObject>(); | |
public int currentJuice(){ | |
return myCurrentJuice; | |
} | |
void Awake(){ | |
// TODO: redo all carrying stuff so it is much cleaner and uses multiple character controllers | |
// Get all the character controllers on this object and its children, store them for when this object is carried | |
CharacterController myCC = gameObject.GetComponent<CharacterController>() as CharacterController; | |
if(myCC){ | |
CCradius = myCC.radius; | |
CCheight = myCC.height; | |
CCoffset = myCC.center.y; | |
DestroyImmediate(myCC); | |
}else{ Debug.Log("Object " + gameObject.name + " had no character controller = carrying is going to be screwed up. ToDO: fix this bullshit carrying code"); } | |
// juiceAtRuntime = myCurrentJuice; | |
} | |
void Start(){ | |
// store internal max as public maxJuice | |
max = maxJuice; | |
// not sure what this is doing... | |
scalingFromGun = false; | |
// derive what my stored Juice should be from my scale | |
float reverseScale = Mathf.Log(transform.localScale.x) / Mathf.Log(scaleSpeed); | |
myCurrentJuice = (int)(reverseScale * scaleFactor); | |
ScaleMe(myCurrentJuice); | |
// myCurrentJuice = Helpers.RemapRange(transform.localScale.x, 0.00, 10.00, min, max); //was commented out in old script | |
juiceReadoutObject.text = myCurrentJuice.ToString(); | |
if(mesh == null) | |
mesh = transform.Find("Mesh").gameObject; | |
// store starting position/juice/scale/rotation | |
startPos = transform.position; | |
startJuice = myCurrentJuice; | |
startScale = transform.localScale; | |
startRot = transform.rotation; | |
// our current scale starts as transform's localscale | |
myCurrentScale = transform.localScale; | |
// TODO: logic for scaleable object parent/children zones | |
// Get the list of all the scaleableobject children | |
// Add to a new arraylist, removing the root gameobject | |
// This is our list of children so we can push mass to them | |
// Then we should disconnect children from parent if we pick up ze objects | |
// var c: ScaleableObject = gameObject.GetComponentInChildren(ScaleableObject); | |
// if(c && c.gameObject.transform.parent != gameObject.transform ){ | |
// hasScaleableChild = true; | |
// Debug.Log("1"); | |
// } | |
// else | |
// { | |
// hasScaleableChild = false; | |
// } | |
} | |
public void Reset(){ | |
if(!rigidbody.isKinematic) | |
rigidbody.velocity = Vector3.zero; | |
transform.localPosition = startPos; | |
transform.localScale = startScale; | |
transform.rotation = startRot; | |
ScaleMe(startJuice); | |
} | |
public Vector3 GetLocalScale(){ | |
return myCurrentScale; | |
} | |
public GameObject GetGO(){ | |
return this.gameObject; | |
} | |
public Vector3 GetStartingPosition(){ | |
return startPos; | |
} | |
public int GetStartingJuice(){ | |
return startJuice; | |
} | |
public Vector3 GetStartingScale(){ | |
return startScale; | |
} | |
public TextMesh GetJuiceReadout(){ | |
return juiceReadoutObject; | |
} | |
public GameObject GetMesh(){ | |
return mesh; | |
} | |
public int GetMin(){ | |
return minJuice; | |
} | |
public int GetMax(){ | |
return maxJuice; | |
} | |
public int GetJuice(){ | |
return myCurrentJuice; | |
} | |
public void ScaleChildren(int newScale){ | |
// Debug.Log("I am " + gameObject.name + " and I gots me a message at " + Time.time); | |
} | |
public void ScaleMeGun(int newJuice){ | |
scalingFromGun = true; | |
ScaleMe(newJuice); | |
scalingFromGun = false; | |
} | |
public void StopScaling(){ | |
// let's clean up those clones! | |
Debug.Log("Stopping scaling: " + gameObject.name); | |
foreach(GameObject clone in clones) | |
{ | |
DestroyImmediate(clone); | |
} | |
clones.Clear(); | |
} | |
public void ScaleMe(int newJuice){ | |
myCurrentJuice = newJuice; | |
// clone colliders of kinematic bodies so we get kinematic-kinematic trigger callbacks. | |
if (this.rigidbody.isKinematic && scalingFromGun && clones.Count == 0) | |
{ | |
Debug.Log("scaling " + gameObject.name + ". It's kinematic, so let's clone its colliders into triggers!"); | |
// clone all sub-gameObjects that have collider components. this is probably not safe for collider hierarchies! | |
Component[] colliders ; | |
colliders = gameObject.GetComponentsInChildren<Collider>(); | |
foreach (Collider col in colliders) | |
{ | |
//Debug.Log("cloning " + col.gameObject.name + " (col = " + col + ")"); | |
GameObject clone = Instantiate(col.gameObject, col.transform.position, col.transform.rotation) as GameObject; | |
// wtf. cloning an object doesn't preserve its place in the hierarchy, so the clone is in the wrong place. | |
// but then when you reinsert it, it automatically changes its transform, which has to be re-copied...? confusing. | |
// STEVE SEZ: I changed the overload of Instantiate you're using - see above. The version of Instantiate where you specify pos, rot is actually faster anyway! | |
clone.transform.parent = col.gameObject.transform.parent; | |
// clone.transform.localPosition = col.gameObject.transform.localPosition; | |
// clone.transform.localRotation = col.gameObject.transform.localRotation; | |
// clone.transform.localScale = col.gameObject.transform.localScale; | |
// make all cloned colliders triggers | |
Component[] clonedColliders; | |
clonedColliders = clone.GetComponentsInChildren<Collider>(); | |
foreach (Collider clonedCol in clonedColliders) | |
{ | |
clonedCol.isTrigger = true; | |
} | |
// track clones for later destruction | |
clones.Add(clone); | |
} | |
} | |
// new scale is not linear; it's scaleSpeed raised to the power of the new mass # divided by scalePower. This is kinda weird and hacky and these vars should be renamed... | |
float newScale = Mathf.Pow(scaleSpeed, newJuice/scaleFactor); | |
// as long as the new scale is something valid, set the local scale of the object | |
if (newScale != Mathf.Infinity) { | |
transform.localScale = new Vector3(newScale, newScale, newScale); | |
myCurrentScale = new Vector3(newScale, newScale, newScale); | |
// take the colliders out of PhysX and put them back in to scale them | |
ResetColliders(); | |
// update the mass readout | |
juiceReadoutObject.text = myCurrentJuice.ToString(); | |
// let the scaleable children of the object know they should scale too. TODO: rewrite this (it's not hooked up anyway!) | |
// BroadcastMessage("ScaleChildren", newScale); | |
//If children have ScaleObject script, do scale on them too | |
// var test = GetComponentsInChildren(Transform); | |
// for(var t in test){ | |
// Debug.Log("GO = " + t.name); | |
// if(t.GetComponent(ScaleableObject)){ | |
// t.GetComponent(ScaleableObject).ScaleMe(newScale); | |
// } | |
// } | |
} | |
} | |
void IgnoreMyCollision(Collider otherCollider){ | |
collidersToIgnore.Add(otherCollider); | |
Physics.IgnoreCollision(collider, otherCollider); | |
} | |
void RefeshCollisionIgnore(){ | |
List<Collider> deadColliders = new List<Collider>(); | |
foreach(Collider col in collidersToIgnore){ | |
if( col == null){ | |
deadColliders.Add(col); | |
continue; | |
} | |
Physics.IgnoreCollision(collider, col); | |
} | |
foreach(Collider dead in deadColliders){ | |
collidersToIgnore.Remove(dead); | |
} | |
} | |
public void ResetColliders(){ | |
gameObject.SetActive(false); | |
gameObject.SetActive(true); | |
// transform.active = false; | |
// transform.active = true; | |
RefeshCollisionIgnore(); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment