Skip to content

Instantly share code, notes, and snippets.

@SteveSwink
Created February 27, 2013 02:37
Show Gist options
  • Save SteveSwink/5044505 to your computer and use it in GitHub Desktop.
Save SteveSwink/5044505 to your computer and use it in GitHub Desktop.
Scaleable object script
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