用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);
}
}