What’s really poignant about your question is that you have a simple copy/paste error in your code. Notice on lines 21 and 22, you’re checking for ScriptB instead of ScriptC, as I’m sure you intended. In any case, it’s a good idea to avoid repetitive code for this reason (among others).
Anyway, it’s hard to say exactly how this code could be improved without knowing more about what all these scripts have in common. Ideally, they would all implement a common base class, so then you could just have one of these blocks where you GetComponent(), and iterate over the results, calling (ideally) a common method on all of them.
You also don’t need to call GetComponent before calling GetComponents each time. Even if just to clean up one of these blocks, the following would be better:
foreach (var a in object.GetComponents<ScriptA>())
{
a.Action1();
}
No null-check is needed.
Another thing to keep in mind is that if you’re calling this code on the same objects a lot (like every frame) it would be better to cache the results of GetComponents, so you’re not having that lookup expense every frame.
But care to share more about what the various scripts have in common?
Sorry about that
Its say something else in actual code, I copy/pasted it here and then change it to ABC for example
It’s basically doing different things if a button is pressed, like scriptA is for enabling/disabling object if a button is clicked, and B is for fading in/fading out using tween, etc.
Its couple different script with OnMouseDown() to execute the action, but what I want to do is to change it to controller (controlling cursor with analog stick). so those code currently run from my cursor if my raycast detect a collider and pressing a button
Well, the key to being able to simplify and reuse code is to find what a bunch of things have in common, and structure your code to perform one action that works on many things. In this case, the “many things” might be too different from each other to really benefit from trying to reuse much of this code. You’re probably fine with just one foreach loop per component type.
But if I were doing something like this to lots of classes, and they were reasonably similar (find some component, call some method on it), I’d probably set up a method to handle this generically. Here’s an example, where I’d also defined your scripts just so the code sort of work:
// Just redefining your three classes here, so we have something to work with.
public class ScriptA : MonoBehaviour
{
public void Action1() { Debug.Log("ScriptA-Action1"); }
}
public class ScriptB : MonoBehaviour
{
public void Action2() { Debug.Log("ScriptB-Action2"); }
}
public class ScriptC : MonoBehaviour
{
public void Action3() { Debug.Log("ScriptC-Action3"); }
}
// This is the method you'd end up calling.
public void DoActions()
{
CallAction<ScriptA>(this.gameObject, (script) => script.Action1());
CallAction<ScriptB>(this.gameObject, (script) => script.Action2());
CallAction<ScriptC>(this.gameObject, (script) => script.Action3());
}
// This is the generic method that gets called three times, once for each of the three kinds of Script class.
private void CallAction<T>(GameObject go, Action<T> action)
{
foreach (var component in go.GetComponents<T>())
{
action(component);
}
}
This feels like overkill for such a simple case, but it’s probably a good example of how some code can be simplified using a generic method. There’s still some copy/paste risk, as each call to CallAction looks very similar to each other call.