[C#] System.Timers.Timer VS MonoBehaviour.Invoke

Cette section est destinée aux scripts partagés par la communauté. Chaque post est destiné à un script. Suivez bien les recommandations.
Avatar de l’utilisateur
ZJP
Messages : 5745
Inscription : 15 Déc 2009 06:00

[C#] System.Timers.Timer VS MonoBehaviour.Invoke

Message par ZJP » 22 Juin 2017 22:05

Bonjour,

Pour Moons (sisi :mrgreen: , ce projet si looong !!!) j'ai décidé de ne pas utiliser la State Machine de Mecanim, et donc de coder cela en...dur.

Exemple d'Animator:
Image

Les délais entre animations étant un passage obligé, j'ai commencé par utiliser l'Invoke d'Unity, malgré sa mauvaise réputation du au GC.

Après moult tests, j'en suis maintenant a préférer une solution via l'API standard de Mono/C# : le System.Timers.Timer

Un exemple valant mieux que de longs discours
Les deux codes activent une succession de timers avant de boucler le processus. Jetez un œil au Profiler (et à la fenêtre de Stats) . C'est édifiant surtout avec les Debug.Log "activés"



Version MonoBehaviour.Invoke

Code : Tout sélectionner

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

using System.Timers;

public class CInvoke : MonoBehaviour {

	void Start () {
		Invoke("OnIdleMove", 1.0f);
	}

	private void OnIdleMove() {
		Debug.Log("OnIdleMove");
		Invoke("OnIdleRandom", 0.010f);
	}

	private void OnIdleRandom() {
		Debug.Log("OnIdleRandom");
		Invoke("OnInitSpeed", 0.010f);
	}

	private void OnInitSpeed() {
		Debug.Log("OnInitSpeed");
		Invoke("OnNextMove", 0.010f);

	}
	
	private void OnNextMove() {
		Debug.Log("OnNextMove");
		Invoke("OnStopVitesse", 0.010f);

	}

	private void OnStopVitesse() {
		Debug.Log("OnStopVitesse");
		Invoke("OnIdleMove", 0.010f);
	}
	

	void Update(){
		if (Input.GetKeyDown("q")){
			if(EditorApplication.isPlaying) 
			{
				UnityEditor.EditorApplication.isPlaying = false;
			}
			enabled = false; // déactivation du script
		}
	}
}




Version System.Timers.Time

Code : Tout sélectionner

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

using System.Timers;

public class CTimer : MonoBehaviour {

	private System.Timers.Timer Timer_IdleMove;
	private System.Timers.Timer Timer_IdleRandom;
	private System.Timers.Timer Timer_InitSpeed;
	private System.Timers.Timer Timer_NextMove;
	private System.Timers.Timer Timer_StopVitesse;
	private const int _OnIdleMove    = 0;
	private const int _OnIdleRandom  = 1;
	private const int _OnInitSpeed   = 2;
	private const int _OnNextMove    = 3;
	private const int _OnStopVitesse = 4;


	private void Start () {

		Timer_IdleMove = new System.Timers.Timer();
//		Timer_IdleMove.Elapsed += new ElapsedEventHandler(OnIdleMove);
		Timer_IdleMove.Elapsed += OnIdleMove; //ou

		Timer_IdleRandom = new System.Timers.Timer();
		Timer_IdleRandom.Elapsed += OnIdleRandom;

		Timer_InitSpeed = new System.Timers.Timer();
		Timer_InitSpeed.Elapsed += OnInitSpeed;

		Timer_NextMove = new System.Timers.Timer();
		Timer_NextMove.Elapsed += OnNextMove;

		Timer_StopVitesse = new System.Timers.Timer();
		Timer_StopVitesse.Elapsed += OnStopVitesse;

		_Invoke(_OnIdleMove, 1000);
	}
	
	private void _Invoke(int func, float delais){
		switch (func) {
			case _OnIdleMove:
				Timer_IdleMove.Interval = delais;
				Timer_IdleMove.Start();
				break;
			case _OnIdleRandom:
				Timer_IdleRandom.Interval = delais;
				Timer_IdleRandom.Start();
				break;
			case _OnInitSpeed:
				Timer_InitSpeed.Interval = delais;
				Timer_InitSpeed.Start();
				break;
			case _OnNextMove:
				Timer_NextMove.Interval = delais;
				Timer_NextMove.Start();
				break;
			case _OnStopVitesse:
				Timer_StopVitesse.Interval = delais;
				Timer_StopVitesse.Start();
				break;
		}
	
	}


	private void OnIdleMove(object source, ElapsedEventArgs e) {
		Timer_IdleMove.Stop();
		Debug.Log("OnIdleMove");
		_Invoke(_OnIdleRandom, 10);
	}

	private void OnIdleRandom(object source, ElapsedEventArgs e) {
		Timer_IdleRandom.Stop();
		Debug.Log("OnIdleRandom");
		_Invoke(_OnInitSpeed, 10);
	}

	private void OnInitSpeed(object source, ElapsedEventArgs e) {
		Timer_InitSpeed.Stop();
		Debug.Log("OnInitSpeed");
		_Invoke(_OnNextMove, 10);
	}
	
	private void OnNextMove(object source, ElapsedEventArgs e) {
		Timer_NextMove.Stop();
		Debug.Log("OnNextMove");
		_Invoke(_OnStopVitesse, 10);
	}

	private void OnStopVitesse(object source, ElapsedEventArgs e) {
		Timer_StopVitesse.Stop();
		Debug.Log("OnStopVitesse");
		_Invoke(_OnIdleMove, 10);
	}
	
	
	private void OnDisable() {
		Timer_IdleMove.Close();
		Timer_IdleRandom.Close();
		Timer_InitSpeed.Close();
		Timer_NextMove.Close();
		Timer_StopVitesse.Close();
	}
	
	private void Update(){
		if (Input.GetKeyDown("q")){
			OnDisable();
			if(EditorApplication.isPlaying) 
			{
				UnityEditor.EditorApplication.isPlaying = false;
			}
			enabled = false; // déactivation du script
		}
	}
}

Dernière édition par ZJP le 11 Juil 2017 17:16, édité 1 fois.

Avatar de l’utilisateur
ZJP
Messages : 5745
Inscription : 15 Déc 2009 06:00

Re: [C#] System.Timers.Timer VS MonoBehaviour.Invoke

Message par ZJP » 24 Juin 2017 15:38

MAJ de l'exemple avec System.Timer : ajout d'un fonction "_Invoke" pour coller le plus que possible à l'originale d'Unity, sans les "strings" toutefois.

Avatar de l’utilisateur
Max
Messages : 8763
Inscription : 30 Juil 2011 13:57
Contact :

Re: [C#] System.Timers.Timer VS MonoBehaviour.Invoke

Message par Max » 24 Juin 2017 17:27

merci pour ce partage JP ;)
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

Avatar de l’utilisateur
ZJP
Messages : 5745
Inscription : 15 Déc 2009 06:00

Re: [C#] System.Timers.Timer VS MonoBehaviour.Invoke

Message par ZJP » 26 Juin 2017 04:09

Max a écrit :merci pour ce partage JP ;)
:-D

Répondre

Revenir vers « Scripts »