Search code examples
c#unity-game-engineaugmented-realityvuforiagameobject

C# ScaleUp Gameobj on every OnTrackingFound Unity + Vuforia


i tried everything but can not get it up and running. Currently i am testing with Unity3d 2021.3.9f and Vuforia 10.14.4.

My aim is to track an ImageTarget and everytime an ImageTarget is FOUND, the explicit GameObjects should scaleUp til a predefined value (GameObjects smoothly scaleUp and not just be there). When the ImageTarget gets LOST, the GameObjects should disappear and the script should reset/stop. when the ImageTarget is FOUND again, the GameObjects should scaleUp again like at the very first time etc.

BUT...

When i add a c#-script (in Update it is scaling from value1 to value2) on my GameObject the script starts as soon as Unity starts - no matter if the ImageTarget has been FOUND or not. And it never resets the values, therefore when the ImageTarget is FOUND again the script is not executed from the beginning and the scaleUp animation of the GameObject is not executed anymore.

I really have no clue haw to handle this. Are there any tutorials out there, where the new DefaultObserverEventHandler is discussed. I also tried to embed the (to-be-scaled) GameObject with its ScaleUP-Script attached in the DefaultObserverEventHandler (in the INSPECTOR) but could not achieve the desired result with activating and deactivating on FOUND or LOST.

I would really appreciate any hint/help - this would be more than awesome.

Best, milla


Solution

  • To implement behaviors for the OnTrackingFound and OnTrackingLost events of the DefaultObserverEventHandler, you can do the following steps (see Add Stuff to Target Vuforia Unity

    1. Create a script which inherits from DefaultObserverEventHandler
    2. Attach it to your image target
    3. Reference your GameObject you want to scale when tracking the image for example via the inspector as a public property
    4. Overwrite the OnTrackingFound and OnTrackingLost methods from the DefaultObserverEventHandler class and implement your behavior

    For scaling I suggest using a Coroutine instead of the Update function. However, using a bool in combination with Update should work too. I have not tested this code but it could look sth like this:

    using UnityEngine;
    using Vuforia;
    using System.Collections;
    
    public class ImgTargetHandler: DefaultObserverEventHandler
    {
        // Object to be put on image target and scaled
        public GameObject targetObj;
        // Target scale (Set in inspector)
        public Vector3 targetScale = new Vector3(2.0f, 2.0f, 2.0f);
        // Default scale of object
        public Vector3 defaultScale = new Vector3(1.0f, 1.0f, 1.0f);
        // Duration of scaling (Set in inspector)
        public float duration = 2.0f;
    
        // Overwrite OnTrackingFound
        protected override void OnTrackingFound()
        {
            base.OnTrackingFound();
    
            // Custom behavior when tracking found (e.g. spawn object and scale)
            StartCoroutine(ScaleObject());
        }
    
        // Overwrite OnTrackingLost
        protected override void OnTrackingLost()
        {
            base.OnTrackingLost();
    
            // Custom behavior when tracking lost (e.g. make obj disappear)
            targetObj.SetActive(false);
        }
    
        // Coroutine to scale the object over time
        IEnumerator ScaleObject()
        {
            // Enable object again
            targetObj.SetActive(true);
    
            // Reset to default scale
            targetObj.localScale = defaultScale;
    
            // Track passed time
            float elapsedTime = 0.0f;
    
            // As long as passed time smaller than specified duration
            while (elapsedTime < duration)
            {
                // Calculate the current scale based on the elapsed time and set it
                float t = elapsedTime / duration;
                targetObj.localScale = Vector3.Lerp(defaultScale, targetScale, t);
    
                // Increased elapsed time
                elapsedTime += Time.deltaTime;
    
                yield return null;
            }
    
            // Set the final scale as lerp does not hit final value exactly
            targetObj.localScale = targetScale;
        }
    }