- Home /
Debugging - Scale Collectible
Hi guys,
I've been working on a script that grows / shrinks a rigid body asset (including the player) on trigger. I currently have 2 scripts; "Collectible" for the the trigger to apply the effect and "Effects" which is added to the rigid body collision object and makes the scale change.
I've been working on it a while and hit a maths wall with how to stack these effects smoothly - resizing to normal is fine, but when adding new collectibles the animation jumps back towards normal size. Can anyone see where I've gone wrong? I think I've isolated it to the following section;
 // Start Transition
 if(timer > duration - transitionDuration) {
     if(modifier != prevModifier) {
        prevModifier = modifier * (duration - timer);
        transform.localScale = defaultScale * (1 + prevModifier);
     }
 }
(On stacking, timer is set back to duration and modifier is increased / decreased.)
Also, any tips on making this generic to any variable (speed etc) without too much code repetition? (eg. Is variable reference forwarding possible?)
I have included the rest of my code below and hope other find it useful.
Effects
 using UnityEngine;
 using System.Collections;
 
 public class Effects : MonoBehaviour {
     
     // The types of attribute effects available
     public enum EffectTypes {Scale}
     public EffectTypes effectType = EffectTypes.Scale;
     
     // Modifier controls
     public float modifier = 0.5f;        // The modifier to aim for
     private float prevModifier = 0;        // The staggered modifier previously used in calculations
     public float minModifier = -0.5f;    // Minimum modifier value (avoids gameObject flipping etc)
     public float maxModifier = 1.0f;    // Maximum modifier value (avoids growing endlessly)
     
     // Essential controls
     public bool stackEffects = true;    // Do the effects stack?
     public float stackAmount = 0.25f;    // Percent of new modifier added when stacking
     private float timer = 5;            // Controls the countdown
     
     // Transition durations
     public float duration = 5;            // Length the effect lasts in seconds
     public float transitionDuration = 1;// Length of the start / end transitions
     
     // Type specific stored values
     private Vector3 defaultScale;        
     
     // Preset the stored animations
     void Awake() {
         // Initialise the game object variables
         defaultScale = transform.localScale;
         
         // Ensure the variables are valid
         modifier = Mathf.Clamp(modifier, minModifier,maxModifier);
         stackAmount = Mathf.Clamp (stackAmount, 0.01f, 1);
         transitionDuration = Mathf.Clamp (transitionDuration, 0.01f, duration / 2);
     }
     
     // Apply the effect and control timer
     void Update() {
         if(effectType == EffectTypes.Scale) {
             ApplyScale();
         }
         timer -= Time.deltaTime;
     }
     
     // Apply the effect to the scale variable
     public void ApplyScale() {
         // Start Transition
         if(timer > duration - transitionDuration) {
             if(modifier != prevModifier) {
                 prevModifier = modifier * (duration - timer);
                 transform.localScale = defaultScale * (1 + prevModifier);
             }
         }
         // Inbetween transitions
         else if(timer > transitionDuration ) { }
         // End transition
         else if(timer > 0) {
             transform.localScale = defaultScale + defaultScale * modifier * timer;
         }
         // Destroy script on completion
         else {
             transform.localScale = defaultScale;
             Destroy (this);
         }
     }
     
     // Directly set the modifier to a value
     public void SetModifier(float mod) {
         modifier = Mathf.Clamp(mod, minModifier, maxModifier);
         timer = duration;
     }
     
     // Reset the timer, and if stackable, stack
     public void CombineEffects(float mod) {
         timer = duration;
         
         // If stack effects is enabled, stack by the stack amount
         if(stackEffects) 
             SetModifier(modifier + mod * stackAmount);
     }
 }
Collectible
 using UnityEngine;
 using System.Collections;
 
 public class Collectible : MonoBehaviour {
     
     public Effects.EffectTypes effect;
     public float modifier = 0.5f;
     
     void OnTriggerEnter(Collider col) {
         if(col.gameObject.GetComponent<Rigidbody>() != null) {
             Effects[] eff = col.gameObject.GetComponents<Effects>();
             bool found = false;
             
             // Determine if the effect has already been applied
             if(eff != null) {
                 for(int i = 0; i < eff.Length; i ++){
                     // If the effect is the same, reset the duration and end the loop
                     if(eff[i].effectType == effect){
                         eff[i].CombineEffects(modifier);
                         found = true;
                         i = eff.Length;
                         
                         // Destroy the collectable
                         Destroy(gameObject);
                     }
                 }
             }
             
             // If there is no effect, apply it
             if(!found || eff == null) {
                 Effects newEffect = col.gameObject.AddComponent(typeof(Effects)) as Effects;
                 if(modifier != 0) {
                     newEffect.SetModifier(modifier);
                 }
                 // Destroy the collectable
                 Destroy(gameObject);
             }
         }
     }
 }
Edit: Cleanup to shorten and refine Effects script. *Edit: Figured out clamping to remove flipping problem.
For ease of testing, I'll also attach my current respawn code. Just set the respawnTime to positive.
 using UnityEngine;
 using System.Collections;
 
 public class SpawnPoint : $$anonymous$$onoBehaviour {
     
     public GameObject spawns;        // Object to spawn
     public float respawnTime = -1;    // Default time between spawning
     public float respawnRandom = 2;    // Time variation between spawning
     public float respawnHeight = 1; // The height at which the collectable spawns
     
     private float timer = -1;        // count down timer
     private GameObject currInstance;
     
     void Start () {
         Spawn();
     }
     
     // Update is called once per frame
     void Update () {
         if(respawnTime != -1 && currInstance == null) {
             if(timer > 0) {
                 timer -= Time.deltaTime;
             }
             else {
                 Spawn();
                 timer = Random.Range(respawnTime - respawnRandom/2, respawnTime + respawnRandom/2);
             }
         }
     }
     
     // Instantiate the object
     public void Spawn() {
         if(!currInstance) {
             currInstance = Instantiate(spawns) as GameObject;
             currInstance.transform.parent = transform;
             Vector3 newPosition = transform.position;
             newPosition.y += respawnHeight;
             currInstance.transform.position = newPosition;
         }
     }
 }
Your answer
 
 
              koobas.hobune.stream
koobas.hobune.stream 
                       
                
                       
			     
			 
                