Jump to content
Unity Insider Forum

Get[Safe]Component


Recommended Posts

Wer kennt das nicht: Prefab gebaut und vergessen irgendwelche Scripts anzuhängen... ;)

Da gibt es wie immer verschiedene Möglichkeiten sowas abzufangen.

Ein Weg, der mir ganz gut gefällt ist, einfach eine eigene "GetComponent"-Methode zu basteln, einem im Zweifelsfall etwas unter die Arme greift..

Ursprünglich kommt sie aus diesem Blog: http://devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/ ,wurde ein wenig modifiziert und in (m)ein Helferlein eingebaut.

using System;
using UnityEngine;

namespace GameFramework
{
   /// <summary>
   ///
   /// </summary>
   public static class MonoBehaviourExtensions
   {
   /// <summary>
    ///
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="behaviour"></param>
    /// <returns></returns>
    public static T GetSafeComponent<T>(this MonoBehaviour behaviour) where T : Component
    {
	    return GetSafeComponent<T>(behaviour.gameObject);
    }

    /// <summary>
    ///
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="gameObject"></param>
    /// <returns></returns>
    public static T GetSafeComponent<T>(this GameObject gameObject) where T : Component
    {
	    var component = gameObject.GetComponent<T>();

	    if (component != null) return component;
	    Debug.LogWarning("Expected to find component of type [ " + typeof(T) + " ] but found none", gameObject);

	    Debug.LogWarning(
		    "Trying to add Component [ " + typeof(T) +
		    " ], just to prevent errors. MAYBE THE SCRIPT NEEDS TO BE SET UP!!!", gameObject);
	    try
	    {
		    Debug.LogWarning("Added Component [ " + typeof(T) + " ] . MAYBE THE SCRIPT NEEDS TO BE SET UP!!!",
			    gameObject);
		    return gameObject.AddComponent<T>();
	    }
	    catch (Exception)
	    {
		    Debug.LogError("Oh oh, couldn´t add Component [ " + typeof(T) + " ]", gameObject);
	    }
	    return null;
    }

   }
}

 

Um nun GetSafeComponent<ClassName>() anstatt GetComponent<ClassName>() nutzen zu können, kann man Folgendes machen:

using UnityEngine;

namespace GameFramework
{
public abstract class BaseTemplate : MonoBehaviour
{
	public string Name = "Unknown";

	/// <summary>
	///
	/// </summary>
	/// <typeparam name="T"></typeparam>
	/// <returns></returns>
	public T GetSafeComponent<T>() where T : Component
	{
		return MonoBehaviourExtensions.GetSafeComponent<T>(this);
	}
}
}

 

using UnityEngine;
using GameFramework;
public class Actor : BaseTemplate
{

   private AnimationController _animationController; // AnimationController derives from MonoBehaviour
   private HealthController _healthController;
   void Awake()
   {
       Name = "Hans";
       _animationController = GetSafeComponent<AnimationController>();
       _healthController = gameObject.GetSafeComponent<AnimationController>();
   }
}

Im Gegensatz zu GetComponent<ScriptName> ist das nur unwesentlich mehr Schreibarbeit.

bearbeitet von AgentCodeMonkey
Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich bin kein Freund von dieser art Unterstützung (wenn die Komponente fehlt sollte man sie selbst hinzufügen um den Fehler komplett zu beseitigen) aber für den einen oder anderen sicher sehr nützlich.

 

Dennoch habe ich ein paar Punkte die das Script verbessern würden:

  1. Mach GetSafeComponent zu einer extension Method an GameObject/MonoBehaviour, dadurch hast du das GameObject und musst es nicht immer beim Aufruf übergeben.
  2. AddComponent liefert dir die neue Komponente zurück, returne den Wert gleich dann brauchst du nicht noch extra GetComponent.

Link zu diesem Kommentar
Auf anderen Seiten teilen

@ Marrrk

Jupp, deshalb wirft es die Warnungen!

Es ist nicht gedacht um alles zu automatisieren, sondern um nicht gleich 1000 Fehler zu schmeissen. Eher ne Art Gedächtnisstütze, falls man doch mal was vergessen hat.

Ansonsten gute Ideen^^ werde ich mal machen.

 

@ Schlumpf

Nunja, wenn du deine Scripts in der Awake oder Start Methode cachst, wovo ich ausgehe, hängt es automatisch das fehlende Script an, allerdings fehlen dir dann die Einstellungen durch den Inspector. Eigentlich soll es wie bereits gesagt dazu dienen Warnungen zu werfen und nicht gleich mit Fehlern um sich werfen. Wie Marrrk schon schreibt, das mag für den ein oder anderen nicht passen und am Ende sollte man es natürlich so machen wie Marrrk schreibt: Script von Hand auf das Objekt ziehen.

Wenn man allerdings die GetSafeComponent Methode nutzt, bleibt das Spiel weiterhin spielbar.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Lädt...
×
×
  • Neu erstellen...