Jump to content
Unity Insider Forum

aktivieren/deaktivieren des "Animator" per Scipt


coldstone

Recommended Posts

Hallo zusammen,

ich stehe vor folgendem Problem.

Und zwas möchte ich einen "Animator", den ich an ein Object angefügt habe, per skript aktivieren oder deaktivieren.

Ich finde die Methode hierfür irgendwie nicht.

Die idee ist durch eine "raycast" zu überprüfen ob ein Objekt 3 sekunden lang angeguckt wird. Falls Ja soll ein Timer animiert werden. Falls der "Raycast" das Objekt nicht mehr "anguckt",

soll die Animation wieder auf "null" gehen.

Ich hoffe ich konnte es grob erklären. :)

Habe dem GameObject einen Animator im Editor hinzugefügt, und diesen deaktivert.

Beim Raycast Hit soll er dann aktiviert werden, sodaß die Animation abgespielt wird.

Mein Code:

 

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Timeline;
using TMPro;
using UnityEngine.UI;

public class collisionTimer : MonoBehaviour
{
    public UnityEvent onRaycastHit;
    public GameObject instruction1;
    public GameObject instruction2;
    private Animator animator;

    void Start()
    {
        animator = GetComponent<Animator>();
       // animator.StopPlayback();
       // instruction1.GetComponent<Animator>().speed = 0;
    }
  
        internal void FireCollision(GameObject hitting)
        {

            if (hitting.Equals(instruction1))
            {

                onRaycastHit.Invoke();
                Debug.Log("Kreis getrofffen");
            animator.StartPlayback(); <--- mit welcher Methode ???

            }  
    } 
}

 

habe irgendwie nach eine methode wie "animator.Enabled(true)" gesucht, aber leider gibt es für den Animator nicht eo eine Methode.

Habe auch schon mehrere methoden aus der Unty Doc versucht aber die Animation startet nicht

Wäre super dankbar für einen Tip.

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 30 Minuten schrieb chrische5:

Hallo

 


_animator.gameObject.SetActive(false);

 

Das müsste gehen. Ich habe mir aber nicht dein Problem angeschaut, sondern nur die Überschrift bearbeitet.

 

Christoph

Damit wird leider das "GameObject" selber deaktiviert, aber nicht der "Animator".

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 2 Stunden schrieb Sascha:

Animator ist ein Behaviour, also einfach Behaviour.enabled auf false setzen.


_animator.enabled = false;

 

Soweit ok. Nur habe ich das problem, sobald meine Raycast Hit aus dem GameObject bereich raus ist, soll die Animation gestopt werden.

In diesem Beispiel, spielt die Animation bis zum ende weiter, auch wenn ich das GameObject nicht mehr treffe.

Es soll die Animation, so lange abgespielt werden, solange der RayCast mein Object trifft. Falls ich vorher aus dem Bereich raus bin,

soll die Animation gestoppt werden. Sobald ich wieder treffe, soll die Animation von vorne beginnen, damit die 3 sekunden Bedinung erfüllt wird.

Dachte mache vielleicht noch eine "else" Bedingung mit rein und packe es in die update methode, so daß es permanent überprüft wird.

Nur hat der Compiler probleme mit dem "internal"

       internal void FireCollision(GameObject hitting)
        {
            if (hitting.Equals(instruction1))
            {
                onRaycastHit.Invoke();
                Debug.Log("Kreis getrofffen");
            animator.StartPlayback(); <--- mit welcher Methode ???
            }  
} 

und ohne den funktioniert die ganze Raycast methode nicht.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Warum sollte "FireCollision" denn internal sein? Und was für Probleme hat der Compiler damit?

vor 3 Stunden schrieb coldstone:

Dachte mache vielleicht noch eine "else" Bedingung mit rein und packe es in die update methode, so daß es permanent überprüft wird.

Jup, musst schon durchgehend raycasten.

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 12 Stunden schrieb Sascha:

Warum sollte "FireCollision" denn internal sein? Und was für Probleme hat der Compiler damit?

Jup, musst schon durchgehend raycasten.

 

Wenn ich es nicht "internal" deklariere, dann kommt ein Verweis auf den folgenden Script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class axesFreeze : MonoBehaviour
{
    // See Order of Execution for Event Functions for information on FixedUpdate() and Update() related to physics queries
    public void Update()
    {
        // Bit shift the index of the layer (8) to get a bit mask
        int layerMask = 1 << 8;

        // This would cast rays only against colliders in layer 8.
        // But instead we want to collide against everything except layer 8. The ~ operator does this, it inverts a bitmask.
        layerMask = ~layerMask;

        RaycastHit hit;
        // Does the ray intersect any objects excluding the player layer
        if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, Mathf.Infinity, layerMask))
        {
            Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * hit.distance, Color.yellow);
           // Debug.Log("Did Hit");

            if (hit.collider.gameObject.GetComponent<collision>() != null)
            {
                hit.collider.gameObject.GetComponent<collision>().FireCollision(hit.collider.gameObject);
            }
            if (hit.collider.gameObject.GetComponent<collisionTimer>() != null)
            {
                hit.collider.gameObject.GetComponent<collisionTimer>().FireCollision(hit.collider.gameObject);
            }
        }
    }
}

Mit der Fehlermeldung in der Console, daß "FireCollision" als private deklariert ist.

Assets\Scripts\axesFreeze.cs(30,72): error CS0122: 'collisionTimer.FireCollision(GameObject)' is inaccessible due to its protection level

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich habe es jetzt so gelöst, das ich eine zweite IF-Bedingung eingebunden habe. Falls die Wand hiter den Objekt raycastet wird, dann wird die Animation auf Null gesetzt.

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Timeline;
using TMPro;
using UnityEngine.UI;

public class collisionTimer : MonoBehaviour
{
    public UnityEvent onRaycastHit;
    public GameObject instruction1;
    public GameObject instruction2;
    private Animator animator;

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

    }

    internal void FireCollision(GameObject hitting)
        {

        if (hitting.Equals(instruction1))
        {

            onRaycastHit.Invoke();
            Debug.Log("Kreis getrofffen");
            animator.enabled = true;
        }
        if (hitting.Equals(instruction2))
        {
            onRaycastHit.Invoke();
            Debug.Log("Wand getrofffen");
            animator.Play("Timer", 0, 0f);
        }
    } 
}

Ich glaube nicht, daß es eine ideale Lösung ist, da hinter dem Objekt immer eine imaginärer Objekt vorhanden sein muss um die zweite if-bedingung zu erfüllen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 6 Stunden schrieb coldstone:

Wenn ich es nicht "internal" deklariere, dann kommt ein Verweis auf den folgenden Script:

Ja, private sollte es auch nicht sein, aber mach's halt einfach mal public :D

vor 6 Stunden schrieb coldstone:

Ich glaube nicht, daß es eine ideale Lösung ist

Würde ich auch sagen.

Ich meine... dein Raycast sieht ja höchstwahrscheinlich so aus:

if (Physics.Raycast( ... ))
{
  blub.FireCollision(hit.gameObject);
}

Da wirfst du ja ganz eigenständig die Information weg, ob der Raycast überhaupt etwas getroffen hat. Das geht ja mit dem if unter und ist dann in FireCollision verloren gegangen.

Du kannst einfach diese Stelle erweitern. Entweder, du erweiterst deine Methode, mit null umgehen zu können ("kein Objekt getroffen")...

if (Physics.Raycast( ... ))
{
  blub.FireCollision(hit.gameObject);
}
else
{
  blub.FireCollision(null);
}

...und dann muss FireCollision irgendwie so aussehen...

internal void FireCollision(GameObject hitting)
{
  // Hier Bedingung erweitern
  if (hitting && hitting.Equals(instruction1))
  {
    // ...
    animator.enabled = true;
  }
  else
  {
    animator.enabled = false;
  }
}

...oder du baust eine zweite Methode, die dann stattdessen aufgerufen wird:

if (Physics.Raycast( ... ))
{
  blub.FireCollision(hit.gameObject);
}
else
{
  blub.StopCollision();
}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...