This code works, but isnt there a better way to execute code once?

 public CameraController cam;
 Animator animator;
 bool inspected;
 bool despected;

 void Start()
 {
     animator = GetComponent<Animator>();
 }


 void Update()
 {
     if (cam.CamPosCode == 1 && !inspected)
     {
         despected = false;
         inspected = true;
         GetComponent<Rigidbody>().useGravity = false;
         animator.SetTrigger("Box Inspect");
     }
     else if (cam.CamPosCode == 2 && !despected)
     {
         inspected = false;
         despected = true;
         GetComponent<Rigidbody>().useGravity = true;
         animator.SetTrigger("Box Despect");
     }
 }

Im an ABSOLUTE Beginner so i dont understand alot of diffrent coding words. However my question is, if there is a better way to only execute code ONCE whilst its condition is still running in Update, that doesnt require me to use booleans?

When you change CamPosCode you could invoke an event from your CameraController. Other scripts can subscribe to that event and make their changes, such as here with respect to useGravity and an animation trigger.

I agree with @Lo-renzo that using CameraPositionChanged events here would probably be the best solution.

But in general, if you want to write something that executes over multiple frames, but only once, then you can:

  1. define an async Awaitable Start() method.
  2. Use the await keyword to pause execution of the method until some condition becomes true.
async Awaitable Start()
{
	var animator = GetComponent<Animator>();

	while(cam.CamPosCode < 1)
	{
		await Awaitable.NextFrameAsync();
	}

	BoxInpect();

	while(cam.CamPosCode < 2)
	{
		await Awaitable.NextFrameAsync();
	}
	
	BoxDespect();
}

The async Awaitable Start() thing swallows any exception that might happen, so I don’t think that’s the greatest idea. No animator? Your code will just stop running without any error messages!

@CoolerColin, if your script only has these two modes, a single bool toggle is enough;

public CameraController cam;
private Animator animator;
private bool inspectMode;

void Start()
{
    animator = GetComponent<Animator>();
}

void Update()
{
    var cameraWantsInspectMode = cam.CamPosCode == 1;

    if (cameraWantsInspectMode != inspectMode)
    {
        inspectMode = cameraWantsInspectMode;
        GetComponent<Rigidbody>().useGravity = inspectMode;
        animator.SetTrigger(inspectMode ? "Box Inspect" : "Box Despect");
    }
}

Since your “inspected” and “despected” bools are mutually exclusive, it’s better to just have a single bool that represents the two states. And then you can just use that single bool again to set useGravity and the correct trigger - although honestly your animator looks like it should be using a bool as well? In that case it’d just be animator.SetBoolean("Box Inspect", inspectMode);

You’re right, thanks for pointing that out.

So the correct way is still to use async void Start() instead, without the Awaitable.

I just noticed that Unity’s newer asynchronous programming guides were using async Awaitable Start in many of their examples, and thought that they had improved their architecture at some while I wasn’t looking, so that they’d properly handle event functions that return Awaitable. But I tried it out in Unity 6, and it looks like that’s not the case.