用strangeioc框架实现简单的功能,但每个部分都包含;实现的功能:方块随机移动,会从服务器中随机得到一个分数,当鼠标点击到方块则加一分,并回传到服务器打印出来,且将分数存到模型中;当点击到方块时会有声音,声音的管理专门写了一个自定义窗口来管理所有的音效。
strangeioc框架可从GitHub上获取
点击打开链接,也可在unity中Asset store中获取。
1. Demo1ContextView.cs
此脚本是Root层,继承自ContextView,启动框架,调用,即本工程的Demo1Context。
using strange.extensions.context.impl;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Demo1ContextView : ContextView {
void Awake()
{
this.context = new Demo1Context(this);//启动strangeioc框架(然后调用Demo1Context中的mapBindings)
}
}
2. Demo1Context.cs
using strange.extensions.context.api;
using strange.extensions.context.impl;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Demo1Context : MVCSContext {
public Demo1Context(MonoBehaviour view) : base(view) { }
protected override void mapBindings()//进行绑定映射
{
//manager
injectionBinder.Bind<AudioManager>().To<AudioManager>().ToSingleton();
//model
injectionBinder.Bind<ScoreModel>().To<ScoreModel>().ToSingleton();
//service
//注入绑定
injectionBinder.Bind<IScoreService>().To<ScoreService>().ToSingleton();//以IScoreService创建对象时则以ScoreService创建。 ToSingleton表示这个对象只会在整个工程中生成一个
//command
commandBinder.Bind(Demo1CommandEvent.RequetScore).To<RequestScoreCommand>();//将RequestScoreCommand与Demo1CommandEvent中RequestScore事件绑定,当Mediator中发起对应的事件请求时直接执行RequestScoreCommand中Execute()
commandBinder.Bind(Demo1CommandEvent.UpdateScore).To<UpdateScoreCommand>();
//mediator
mediationBinder.Bind<CubeView>().To<CubeMediator>();//将View与Mediator绑定,当View创建时,会自动创建Mediator
//绑定开始事件 创建一个startcommand
commandBinder.Bind(ContextEvent.START).To<StartCommand>().Once();//Once()表示只绑定一次,当执行之后就解绑
}
}
3. StartCommand.cs
开始命令,做一些初始化工作。
using strange.extensions.command.impl;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 开始命令 startcommand做一些初始化的操作
/// </summary>
public class StartCommand : Command {
[Inject]
public AudioManager audioManager { get; set; }
/// <summary>
/// 当这个命令被执行的时候,默认会调用Excute方法
/// </summary>
public override void Execute()
{
Debug.Log("start command execute!");
//AudioManager的初始化
audioManager.Init();
}
}
4. RequestScoreCommand.cs
从服务器请求得到分数的命令,和Demo1CommandEvent的事件枚举的RequetScore绑定。
using strange.extensions.command.impl; using strange.extensions.dispatcher.eventdispatcher.api; using System.Collections; using System.Collections.Generic; using UnityEngine; public class RequestScoreCommand : EventCommand { [Inject] public IScoreService scoreService { get; set; } [Inject] public ScoreModel scoreModel { get; set; } public override void Execute() { Retain();//此命令都是一次性的,Retain使之不销毁,当OnComplete执行完之后才Release销毁 scoreService.dispatcher.AddListener(Demo1ServiceEvent.RequestScore, OnComplete);//将OnComplete方法与Demo1Service的RequestScore事件进行绑定 scoreService.RequestScore("http://XXX/dd/ddd"); } private void OnComplete(IEvent evt)//IEvent储存的就是参数 { Debug.Log("Request score complete! "+evt.data); scoreModel.Socre = (int)evt.data; scoreService.dispatcher.RemoveListener(Demo1ServiceEvent.RequestScore,OnComplete); dispatcher.Dispatch(Demo1MediatorEvent.ScoreChanged,evt.data);//回传分数 Release(); } }
5. UpdateScoreCommand.cs
using strange.extensions.command.impl;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UpdateScoreCommand : EventCommand {
[Inject]
public ScoreModel scoreModel { get; set; }
[Inject]
public IScoreService scoreService { get; set; }
public override void Execute()
{
scoreModel.Socre++;
scoreService.UpdateScore("http://SS/set/stg", scoreModel.Socre);
dispatcher.Dispatch(Demo1MediatorEvent.ScoreChanged, scoreModel.Socre);
}
}
6. CubeMediator.cs
用于View层和Command层进行交互。
using strange.extensions.context.api;
using strange.extensions.dispatcher.eventdispatcher.api;
using strange.extensions.mediation.impl;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Mediator处理View与Controller层进行交互的
/// 一个View对应一个Mediat
/// </summary>
public class CubeMediator : Mediator {
[Inject]
public CubeView cubeView { get; set; }
[Inject(ContextKeys.CONTEXT_DISPATCHER)]//ContextKeys.CONTEXT_DISPATCHER表示创建了一个全局的dispatcher
public IEventDispatcher dispatcher { get; set; }
public override void OnRegister()
{
cubeView.Init();
dispatcher.AddListener(Demo1MediatorEvent.ScoreChanged, OnScoreChange);
cubeView.dispatcher.AddListener(Demo1MediatorEvent.ClickDown, OnClickDown);
//通过dispatcher发起请求分数的命令
dispatcher.Dispatch(Demo1CommandEvent.RequetScore);
}
public override void OnRemove()
{
dispatcher.RemoveListener(Demo1MediatorEvent.ScoreChanged, OnScoreChange);
cubeView.dispatcher.RemoveListener(Demo1MediatorEvent.ClickDown, OnClickDown);
}
public void OnScoreChange(IEvent evt)
{
cubeView.UpdateScore((int)evt.data);
}
/// <summary>
/// 点击后通过UpdateScoreCommand提交给服务器更新分数
/// </summary>
public void OnClickDown()
{
dispatcher.Dispatch(Demo1CommandEvent.UpdateScore);
}
}
7. CubeView.cs
using strange.extensions.dispatcher.eventdispatcher.api;
using strange.extensions.mediation.impl;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class CubeView : View {
private Text socreText;
[Inject]
public IEventDispatcher dispatcher { get; set; }
[Inject]
public AudioManager audioManager { get; set; }
/// <summary>
/// 做初始化
/// </summary>
public void Init()
{
socreText = GetComponentInChildren<Text>();
}
void Update()
{
transform.Translate( new Vector3(Random.Range(-1, 2), Random.Range(-1, 2), Random.Range(-1, 2))*.2f);
}
void OnMouseDown()
{
//加分
Debug.Log("OnMouseDown");
dispatcher.Dispatch(Demo1MediatorEvent.ClickDown);
audioManager.PlayAudio("Win");
}
public void UpdateScore(int score)//对数据的操作不在View中进行,所以在此只提供了设置的方法,方便Mediator层调用
{
socreText.text = score.ToString();
}
}
8. Demo1CommandEvent.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum Demo1CommandEvent {
RequetScore,
UpdateScore
}
9. Demo1MediatorEvent.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum Demo1MediatorEvent {
ScoreChanged,
ClickDown
}
10. Demo1ServiceEvent.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum Demo1ServiceEvent {
RequestScore
}
11. ScoreService.cs
using System.Collections;
using System.Collections.Generic;
using strange.extensions.dispatcher.eventdispatcher.api;
using UnityEngine;
public class ScoreService : IScoreService
{
[Inject]
public IEventDispatcher dispatcher{ get; set; }
public void OnReceiveScore()
{
int score = Random.Range(0, 100);
dispatcher.Dispatch(Demo1ServiceEvent.RequestScore,score);
}
public void RequestScore(string url)
{
Debug.Log("Requset Score from Url:" + url);
OnReceiveScore();
}
public void UpdateScore(string url, int score)
{
Debug.Log("Update Score to Url:" + url + "new Score:" + score);
}
}
12. 音频管理器(自定义界面)
创建了一个自定义界面用于管理音频。
12.1 AudioWindowEditor.cs
using System.Collections; using System.Collections.Generic; using System.IO; using System.Text; using UnityEditor; using UnityEngine; /// <summary> /// 音效管理面板 /// </summary> public class AudioWindowEditor : EditorWindow { [MenuItem("AudioTool/AudioManager")] static void CreateWindow() { //Rect rect = new Rect(Screen.height / 2, Screen.width / 2, 500, 500); //AudioWindowEditor window = GetWindowWithRect(typeof(AudioWindowEditor), rect,false,"音频管理器") as AudioWindowEditor;//窗口大小固定 AudioWindowEditor window = GetWindow<AudioWindowEditor>("音频管理器"); window.Show(); Debug.Log("Show"); } private string audioName; private string audioPath; private Dictionary<string, string> audioDic = new Dictionary<string, string>(); //private Object audioClip; void OnGUI() { //Debug.Log("OnGUI"); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("音效名字"); EditorGUILayout.LabelField("音效路径"); EditorGUILayout.LabelField("操作"); EditorGUILayout.EndHorizontal(); //将添加进的音频显示出来 foreach (string key in audioDic.Keys) { string value; value = audioDic[key]; EditorGUILayout.BeginHorizontal();//水平布局开始,之间的GUI控件会水平布局 EditorGUILayout.LabelField(key); EditorGUILayout.LabelField(value); if (GUILayout.Button(" 删除 ")) { audioDic.Remove(key); SaveAudioList(); return; } EditorGUILayout.EndHorizontal();//水平布局结束,之间的GUI控件会水平布局 } //EditorGUILayout.TextField("输入文字1", text);//第一个参数表示标签(提示)第二个参数为输入内容 //GUILayout.TextField("输入文字2");//无标签提示,字符串参数为默认值,且不可更改 EditorGUILayout.LabelField("--------------------------------------------------------------------------------------------------------------------------------------"); EditorGUILayout.BeginHorizontal(); audioName = EditorGUILayout.TextField("音效名字", audioName); audioPath = EditorGUILayout.TextField("音效路径", audioPath); EditorGUILayout.EndHorizontal(); //audioClip = EditorGUILayout.ObjectField(audioClip, typeof(AudioClip)); if (GUILayout.Button("添加音效")) { Object o = Resources.Load(audioPath); if (o == null) { Debug.LogWarning("音效不存在于:" + audioPath); audioPath = ""; } else { if (audioDic.ContainsValue(audioPath)) { Debug.LogWarning("已经存在相同的音频!"); } else { Debug.Log("添加成功 " + audioName + " " + audioPath); audioDic.Add(audioName, audioPath); SaveAudioList(); } } } } /// <summary> /// 每秒调用十次 /// </summary> private void OnInspectorUpdate() { LoadAudioList(); } //private string savePath = Application.dataPath + "\\FramWork\\Resources\\audiolist.txt"; private void SaveAudioList() { //string savePath = Application.dataPath + "\\FramWork\\Resources\\audiolist.txt"; StringBuilder sb = new StringBuilder(); //将添加进的音频显示出来 foreach (string key in audioDic.Keys) { string value; value = audioDic[key]; sb.Append(key + "," + value + "\n"); } File.WriteAllText(AudioManager.AudioTextPath, sb.ToString()); } private void LoadAudioList() { //string savePath = Application.dataPath + "\\FramWork\\Resources\\audiolist.txt"; audioDic = new Dictionary<string, string>(); if (File.Exists(AudioManager.AudioTextPath) == false) return; string[] lines = File.ReadAllLines(AudioManager.AudioTextPath); foreach (string line in lines) { if (string.IsNullOrEmpty(line)) continue; string[] keyvalue = line.Split(','); audioDic.Add(keyvalue[0], keyvalue[1]); } } }
12.2 AudioManager.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class AudioManager{ private static string audioTextPathPrefix = Application.dataPath+"\\Framwork\\Resources\\"; private static string audioTextPathMidlle = "audiolist"; private static string audioTextPathPostfix = ".txt"; public static string AudioTextPath { get { return audioTextPathPrefix +audioTextPathMidlle+ audioTextPathPostfix; } } private Dictionary<string, AudioClip> audioClipDict = new Dictionary<string, AudioClip>(); private bool isMute = false;//静音 //public AudioManager() //{ // LoadAudioClip(); //} public void Init() { LoadAudioClip(); } private void LoadAudioClip() { audioClipDict = new Dictionary<string, AudioClip>(); TextAsset ta = Resources.Load<TextAsset>(audioTextPathMidlle); string[] lines = ta.text.Split('\n'); foreach(string line in lines) { if (string.IsNullOrEmpty(line)) continue; string[] keyvalue = line.Split(','); string key = keyvalue[0]; AudioClip value = Resources.Load<AudioClip>(keyvalue[1]); audioClipDict.Add(key, value); } } public void PlayAudio(string name) { if (isMute) return; AudioClip ac; audioClipDict.TryGetValue(name,out ac); AudioSource.PlayClipAtPoint(ac, Vector3.zero); } public void PlayAudio(string name,Vector3 point) { if (isMute) return; AudioClip ac; audioClipDict.TryGetValue(name, out ac); AudioSource.PlayClipAtPoint(ac, point); } }