mirror of
https://gitea.msk.dinamika-avia.ru/Constanta-Design/MI-38.git
synced 2026-01-24 02:25:38 +03:00
1533 lines
60 KiB
C#
1533 lines
60 KiB
C#
using System.Collections;
|
||
using UnityEngine;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using UnityEngine.EventSystems;
|
||
using System.Xml;
|
||
using System.Xml.Serialization;
|
||
using UnityEngine.Networking;
|
||
using System.Text;
|
||
using UnityEngine.UI;
|
||
using TMPro;
|
||
using System.Runtime.InteropServices;
|
||
|
||
|
||
[XmlRoot("Scenario")]
|
||
public class Scenario
|
||
{
|
||
[XmlIgnore]
|
||
public string name;
|
||
[XmlElement("title")]
|
||
public string title;
|
||
[XmlElement("changeTime")] //XmlAttribute
|
||
public string changeTime;
|
||
[XmlElement("needExamCompleted")]
|
||
public bool needExamCompleted;
|
||
|
||
//[XmlIgnore]
|
||
//public string fullFileName;
|
||
[XmlIgnore]
|
||
public bool isModifyed;
|
||
[XmlIgnore]
|
||
public int curMode;
|
||
[XmlIgnore]
|
||
public ScenarioMode curModeSc;
|
||
|
||
[XmlElement("init")]
|
||
public ScenarioMode init = new ScenarioMode();
|
||
[XmlElement("demonstration")]
|
||
public ScenarioMode demo = new ScenarioMode();
|
||
[XmlElement("training")]
|
||
public ScenarioMode train = new ScenarioMode();
|
||
[XmlElement("examination")]
|
||
public ScenarioMode exam = new ScenarioMode();
|
||
}
|
||
public class ScenarioMode
|
||
{
|
||
[XmlElement("action")]
|
||
public List<ScAction> acts = new List<ScAction>();
|
||
}
|
||
public class ScAction
|
||
{
|
||
[XmlAttribute("objectName")]
|
||
public string objName;
|
||
[XmlAttribute("type")]
|
||
public string type; // setState, setStateInRange, openPanel, setTextField, setIntField, switchTo3D, highlightOn, highlightOff,
|
||
// highlightTime, waitForClick, waitForTime, setCurCameraPos, showText, hideText, execScenario, playAudio
|
||
// setSkyBox
|
||
[XmlAttribute("title")]
|
||
public string title;
|
||
|
||
[XmlIgnore]
|
||
public int actNumberToShow=-1;
|
||
|
||
[XmlElement("setState")]
|
||
public actSetState setState;
|
||
|
||
[XmlElement("setStateInRange")]
|
||
public actSetStateInRange setStateInRange;
|
||
|
||
[XmlElement("setTextField")]
|
||
public actSetTextField setTextField;
|
||
|
||
[XmlElement("setIntField")]
|
||
public actSetIntField setIntField;
|
||
|
||
[XmlElement("highlightTime")]
|
||
public actHighlightTime highlightTime;
|
||
|
||
[XmlElement("waitForTime")]
|
||
public actWaitForTime waitForTime;
|
||
|
||
[XmlElement("setCurCameraPos")]
|
||
public actSetCurCameraPos setCurCameraPos;
|
||
|
||
[XmlElement("showText")]
|
||
public actShowText showText;
|
||
|
||
[XmlElement("execScenario")]
|
||
public actExecScenario execScenario;
|
||
|
||
[XmlElement("playAudio")]
|
||
public actPlayAudio playAudio;
|
||
|
||
[XmlElement("switchMFIScreen")]
|
||
public actSwitchMFIScreen switchMFIScreen;
|
||
|
||
[XmlElement("setSkybox")]
|
||
public actSetSkybox setSkybox;
|
||
|
||
[XmlElement("showRect")]
|
||
public actShowRect showRect;
|
||
|
||
public ScAction clone()
|
||
{
|
||
ScAction res;
|
||
byte[] buf = new byte[1024];
|
||
XmlSerializer serializer = new XmlSerializer(this.GetType());
|
||
Stream fs;
|
||
fs = new MemoryStream(buf); //utf8.GetBytes(scText)
|
||
StreamWriter writer = new StreamWriter(fs);
|
||
serializer.Serialize(writer.BaseStream, this);
|
||
writer.Close();
|
||
|
||
fs = new MemoryStream(buf);
|
||
StreamReader reader = new StreamReader(fs);
|
||
res = (ScAction)serializer.Deserialize(reader.BaseStream);
|
||
reader.Close();
|
||
if (res == null)
|
||
Debug.Log("Error: act clone fail");
|
||
//else
|
||
// Debug.Log("act clone: " + res.objName);
|
||
res.actNumberToShow = -1;
|
||
return res;
|
||
}
|
||
}
|
||
//нет необходимости в доп. данных:
|
||
// public class actOpenPanel { }
|
||
// public class actSwitchTo3D { }
|
||
// public class actHighlightOn { }
|
||
// public class actHighlightOff { }
|
||
// public class actWaitForClick { }
|
||
// public class actHighlightOff { }
|
||
// public class actHideText { }
|
||
// actHideRects
|
||
|
||
public class actSetState
|
||
{
|
||
[XmlAttribute("val")]
|
||
public int val;
|
||
[XmlAttribute("name")]
|
||
public string name = "";
|
||
}
|
||
public class actSetStateInRange
|
||
{
|
||
[XmlAttribute("val")]
|
||
public int val;
|
||
[XmlAttribute("sec")]
|
||
public int sec = 0;
|
||
[XmlIgnore]
|
||
public string rangeStr = "";
|
||
}
|
||
public class actHighlightTime
|
||
{
|
||
[XmlAttribute("sec")]
|
||
public int sec;
|
||
}
|
||
public class actWaitForTime
|
||
{
|
||
[XmlAttribute("sec")]
|
||
public int sec;
|
||
}
|
||
public class actShowText
|
||
{
|
||
[XmlAttribute("text")]
|
||
public string text;
|
||
}
|
||
public class actSetTextField
|
||
{
|
||
[XmlAttribute("text")]
|
||
public string text;
|
||
[XmlAttribute("color")]
|
||
public string color;
|
||
}
|
||
public class actSetIntField
|
||
{
|
||
[XmlAttribute("from")]
|
||
public int valFrom;
|
||
[XmlAttribute("to")]
|
||
public int valTo;
|
||
[XmlAttribute("sec")]
|
||
public int sec;
|
||
[XmlAttribute("color")]
|
||
public string color;
|
||
}
|
||
public class actSetSkybox
|
||
{
|
||
[XmlAttribute("name")]
|
||
public string name;
|
||
}
|
||
public class actShowRect
|
||
{
|
||
[XmlAttribute("x1")]
|
||
public int x1;
|
||
[XmlAttribute("y1")]
|
||
public int y1;
|
||
//[XmlAttribute("z1")]
|
||
//public float z1;
|
||
[XmlAttribute("x2")]
|
||
public int x2;
|
||
[XmlAttribute("y2")]
|
||
public int y2;
|
||
//[XmlAttribute("z2")]
|
||
//public float z2;
|
||
}
|
||
public class actExecScenario
|
||
{
|
||
[XmlAttribute("name")]
|
||
public string name;
|
||
[XmlAttribute("fast")]
|
||
public bool fastFlag;
|
||
}
|
||
public class actPlayAudio
|
||
{
|
||
[XmlAttribute("filename")]
|
||
public string filename;
|
||
[XmlIgnore]
|
||
public AudioClip clip = null;
|
||
}
|
||
public class actSwitchMFIScreen
|
||
{
|
||
[XmlAttribute("scrName")]
|
||
public string scrName;
|
||
}
|
||
public class actSetCurCameraPos
|
||
{
|
||
[XmlAttribute("camera")]
|
||
public string camera; // "view" (обзор), "cabin" (кабина, салон)
|
||
[XmlAttribute("fov")] // Field of view
|
||
public int fov;
|
||
[XmlAttribute("viewMode")]
|
||
public int viewMode;
|
||
[XmlElement("position")]
|
||
public uVector3 position;
|
||
[XmlElement("rotation")]
|
||
public uVector3 rotation;
|
||
[XmlElement("scale")]
|
||
public uVector3 scale;
|
||
[XmlElement("scriptOffset")] // для скрипта Макса
|
||
public uVector3 scriptOffset;
|
||
}
|
||
public class uVector3
|
||
{
|
||
[XmlAttribute("x")]
|
||
public float x;
|
||
[XmlAttribute("y")]
|
||
public float y;
|
||
[XmlAttribute("z")]
|
||
public float z;
|
||
public Vector3 toVector3()
|
||
{
|
||
Vector3 v3 = new Vector3();
|
||
v3.x = x; v3.y = y; v3.z = z;
|
||
return v3;
|
||
}
|
||
public Quaternion toQuaternion()
|
||
{
|
||
return Quaternion.Euler(x, y, z); // rotation в сценарии записаны в градусах!
|
||
}
|
||
}
|
||
//----------------------------------------------------------------------------
|
||
|
||
public class Player : MonoBehaviour
|
||
{
|
||
public string state= "empty"; // empty, ready, pause, play
|
||
public string mode; // demo, train, exam
|
||
public string playMode; // play, waitForTime, waitForClick, cameraIsMoving
|
||
Manager man=null;
|
||
GameObject btnPlay, btnPause, actCounterText, progressBar, btnDemoMode, btnTrainMode, btnExamMode;
|
||
public GameObject playerText;
|
||
public Scenario SC = null;
|
||
ScEditor sce = null;
|
||
public List<ScAction> acts;
|
||
int nextAct;
|
||
bool canProgressBarChangePos;
|
||
bool buildInProgress;
|
||
ScenarioMode curScMode;
|
||
float playDelta = 0.25f;
|
||
float playTimeToWait; // playMode = waitForTime
|
||
float cameraMoveCurTime, cameraMoveMaxTime;
|
||
string playCamera;
|
||
GameObject curCamera;
|
||
string waitForClickObjName;
|
||
public List<highlightObj> highlightList = new List<highlightObj>();
|
||
float highlightTimeDelta = 0.25f;
|
||
float setStateInTimeDelta = 0.05f;
|
||
List<setStateInTimeStruct> setStateInTimeList = new List<setStateInTimeStruct>();
|
||
List<UnityObject> buttonAutoUncheckList = new List<UnityObject>();
|
||
List<actShowRect> rectsList = new List<actShowRect>();
|
||
public bool isRectsShowing = false;
|
||
Texture2D lineTex;
|
||
float rectAlpha = 1f;
|
||
bool rectAlphaDir = false;
|
||
float rectW = 1000f;
|
||
float rectH = 1000f;
|
||
|
||
[HideInInspector]
|
||
public bool isFullscreen = false;
|
||
public bool isScEditorCameraMoving = false;
|
||
|
||
class setStateInTimeStruct
|
||
{
|
||
public UnityObject obj;
|
||
public float runTime, runCurTime;
|
||
public int fromState, toState;
|
||
}
|
||
public class highlightObj
|
||
{
|
||
public UnityObject obj;
|
||
public float sec;
|
||
public Renderer[] renderers;
|
||
public List<Material> materials = new List<Material>();
|
||
public List<Material> greenMaterials = new List<Material>();
|
||
public SpriteRenderer[] spriteRenderers;
|
||
public Image[] images;
|
||
public List<Color> spriteColors = new List<Color>();
|
||
public List<Color> imageColors = new List<Color>();
|
||
}
|
||
struct TransformStruct {
|
||
public Vector3 position;
|
||
public Quaternion rotation;
|
||
public Vector3 scale;
|
||
};
|
||
TransformStruct cameraIsMovingFromPos = new TransformStruct();
|
||
int cameraFromFOV, cameraToFOV;
|
||
TransformStruct cameraIsMovingToPos = new TransformStruct();
|
||
|
||
public void Init()
|
||
{
|
||
man = GameObject.Find("Manager").GetComponent<Manager>();
|
||
btnPlay = GameObject.Find("PlayButtons/grey/green/play"); btnPlay.SetActive(true);
|
||
btnPause = GameObject.Find("PlayButtons/grey/green/pause"); btnPause.SetActive(false);
|
||
actCounterText = GameObject.Find("PlayButtons/grey/actCounterText");
|
||
progressBar = GameObject.Find("PlayButtons/ProgressBar");
|
||
btnDemoMode = GameObject.Find("ModeMenu/DemoMenuButton");
|
||
btnTrainMode = GameObject.Find("ModeMenu/LearnMenuButton");
|
||
btnExamMode = GameObject.Find("ModeMenu/TestMenuButton");
|
||
sce = GameObject.Find("ScEditor").GetComponent<ScEditor>();
|
||
state = "empty"; canProgressBarChangePos = true; buildInProgress = false;
|
||
acts = new List<ScAction>();
|
||
lineTex = new Texture2D(1, 1); rectAlpha = 1f;
|
||
|
||
//Debug.Log("Player.Init: InvokeRepeating HighliteRefresh");
|
||
CancelInvoke("HighliteRefresh");
|
||
InvokeRepeating("HighliteRefresh", 0, highlightTimeDelta);
|
||
//if(state == "empty")
|
||
// LoadScenario("qwe"); // debug
|
||
//LoadScenario("System_2"); //debug
|
||
|
||
}
|
||
|
||
void Update()
|
||
{
|
||
if (Input.GetMouseButtonDown(0))
|
||
{
|
||
GameObject curCamera;
|
||
if (man.cabinCamera.activeInHierarchy)
|
||
curCamera = man.cabinCamera;
|
||
else
|
||
curCamera = man.viewCamera;
|
||
Ray ray = curCamera.GetComponent<Camera>().ScreenPointToRay(Input.mousePosition);
|
||
RaycastHit hit;
|
||
if (Physics.Raycast(ray, out hit))
|
||
if (hit.transform.gameObject != null)
|
||
ClickedGO(hit.transform.gameObject);
|
||
}
|
||
|
||
}
|
||
void OnGUI()
|
||
{
|
||
if (isRectsShowing)
|
||
{
|
||
//Vector2 g1 = GUIUtility.ScreenToGUIPoint(p1);
|
||
//Vector2 g2 = GUIUtility.ScreenToGUIPoint(p2);
|
||
foreach (actShowRect r in rectsList)
|
||
{
|
||
DrawLine(r.x1, r.y1, r.x2, r.y1, rectAlpha);
|
||
DrawLine(r.x2, r.y1, r.x2, r.y2, rectAlpha);
|
||
DrawLine(r.x2, r.y2, r.x1, r.y2, rectAlpha);
|
||
DrawLine(r.x1, r.y2, r.x1, r.y1, rectAlpha);
|
||
|
||
//Vector3 g1 = man.cam.WorldToScreenPoint(new Vector3((float)r.x1, (float)r.y1, (float)r.z1));
|
||
//Vector3 g2 = man.cam.WorldToScreenPoint(new Vector3((float)r.x2, (float)r.y2, (float)r.z2));
|
||
//DrawLine(g1.x, g1.y, g2.x, g1.y, rectAlpha);
|
||
//DrawLine(g2.x, g1.y, g2.x, g2.y, rectAlpha);
|
||
//DrawLine(g2.x, g2.y, g1.x, g2.y, rectAlpha);
|
||
//DrawLine(g1.x, g2.y, g1.x, g1.y, rectAlpha);
|
||
}
|
||
if (rectAlphaDir)
|
||
rectAlpha += 0.004f;
|
||
else
|
||
rectAlpha -= 0.004f;
|
||
if (rectAlphaDir && rectAlpha >= 1f) { rectAlpha = 1f; rectAlphaDir = false; }
|
||
if (!rectAlphaDir && rectAlpha <= 0.3f) { rectAlpha = 0.3f; rectAlphaDir = true; }
|
||
}
|
||
}
|
||
void DrawLine(float _x1, float _y1, float _x2, float _y2, float a = 1f) //(int _x1, int _y1, int _x2, int _y2, float a=1f)
|
||
{
|
||
/*Matrix4x4 matrixBackup = GUI.matrix;
|
||
float width = 3.0f;
|
||
GUI.color = new Color(0, 1, 0, a);
|
||
float angle = Mathf.Atan2(y2 - y1, x2 - x1) * 180f / Mathf.PI;
|
||
GUIUtility.RotateAroundPivot(angle, new Vector2(x1, y1));
|
||
GUI.DrawTexture(new Rect(x1 - width / 2f, y1 - width / 2f, Mathf.Max(Mathf.Abs(x1 - x2), Mathf.Abs(y1 - y2)), width), lineTex);
|
||
GUI.matrix = matrixBackup;*/
|
||
|
||
//float scrCoef = ((float)Screen.width / (float)Screen.height) / (16f / 9f);
|
||
float x1 = Screen.width * (0.5f + _x1/ rectW); //1920
|
||
float y1 = Screen.height * (0.5f + _y1 / rectH);// * scrCoef; //1080
|
||
float x2 = Screen.width * (0.5f + _x2 / rectW);
|
||
float y2 = Screen.height * (0.5f + _y2 / rectH);// * scrCoef;
|
||
|
||
Matrix4x4 matrixBackup = GUI.matrix;
|
||
float width = 3.0f;
|
||
GUI.color = new Color(0, 1, 0, a);
|
||
float angle = Mathf.Atan2(y2 - y1, x2 - x1) * 180f / Mathf.PI;
|
||
GUIUtility.RotateAroundPivot(angle, new Vector2(x1, y1));
|
||
GUI.DrawTexture(new Rect(x1 - width / 2f, y1 - width / 2f, Mathf.Max(Mathf.Abs(x1 - x2), Mathf.Abs(y1 - y2)), width), lineTex);
|
||
GUI.matrix = matrixBackup;
|
||
}
|
||
void ClickedGO(GameObject go)
|
||
{
|
||
if (state != "play") return;
|
||
if (playMode != "waitForClick") return;
|
||
if (go == null) return;
|
||
if (man.objects == null)
|
||
{
|
||
Debug.LogError("Player: objects not loaded");
|
||
return;
|
||
}
|
||
UnityObject handlerObj = man.objects.FindHandler(go.name);
|
||
if (handlerObj == null) return;
|
||
if (!handlerObj.enabled) return; // объект выключен - игнорируем
|
||
|
||
if(handlerObj.name == waitForClickObjName)
|
||
{
|
||
playMode = "play";
|
||
man.mouseEnterUI();
|
||
PlayActs();
|
||
}
|
||
else if(handlerObj.name != "Kreslo_KVS" && handlerObj.name != "Kreslo_2P")
|
||
{ // клик в другой объект, что делаем?
|
||
AudioSource beeper = GameObject.Find("beeper").GetComponent<AudioSource>();
|
||
beeper.Play();
|
||
if (mode == "exam")
|
||
{
|
||
playerText.transform.Find("PlayerTextTMP").gameObject.GetComponent<TMP_Text>().text =
|
||
"<color=#aa0000>Ошибка в действиях обучаемого. Режим \"Контроль\" не пройден.\n\n</color><color=#000000><alpha=#AA>Перезагрузите страницу.</color>";
|
||
playerText.SetActive(true);
|
||
// чем наказываем:
|
||
SetMode("exam");
|
||
if (man.mode == "play")
|
||
{
|
||
GameObject.Find("PlayButtons").SetActive(false);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
public void Clicked2D(BaseEventData evData)
|
||
{
|
||
if (man.mode != "play" && man.mode != "scedit") return;
|
||
if (playMode != "waitForClick") return;
|
||
RaycastHit2D hit;
|
||
Ray ray = GameObject.Find("Camera").GetComponent<Camera>().ScreenPointToRay(Input.mousePosition);
|
||
|
||
PointerEventData _pointer = evData as PointerEventData;
|
||
hit = Physics2D.Raycast(ray.origin, Vector2.up);
|
||
if (hit.transform != null && _pointer.button == PointerEventData.InputButton.Left)
|
||
ClickedGO(hit.transform.gameObject);
|
||
}
|
||
|
||
private void LateUpdate()
|
||
{
|
||
if (playMode == "cameraIsMoving")
|
||
{
|
||
cameraMoveCurTime += Time.deltaTime;
|
||
float d = cameraMoveCurTime / cameraMoveMaxTime;
|
||
if (playCamera == "cabin")
|
||
{
|
||
curCamera.transform.position = Vector3.Lerp(cameraIsMovingFromPos.position, cameraIsMovingToPos.position, d);
|
||
curCamera.transform.rotation = Quaternion.Slerp(cameraIsMovingFromPos.rotation, cameraIsMovingToPos.rotation, d);
|
||
//curCamera.GetComponent<Camera>().fieldOfView = (int)Mathf.Lerp((float)cameraFromFOV, (float)cameraToFOV, d); // дергается при плавном изменении :(
|
||
}
|
||
else
|
||
{
|
||
curCamera.transform.rotation = Quaternion.Slerp(cameraIsMovingFromPos.rotation, cameraIsMovingToPos.rotation, d);
|
||
curCamera.transform.position = curCamera.transform.localRotation * curCamera.GetComponent<CameraFree>().offset + curCamera.GetComponent<CameraFree>().target.position;
|
||
curCamera.GetComponent<CameraFree>().offset = Vector3.Lerp(cameraIsMovingFromPos.scale, cameraIsMovingToPos.scale, d);
|
||
}
|
||
|
||
if (cameraMoveCurTime >= cameraMoveMaxTime)
|
||
{
|
||
if (playCamera == "cabin")
|
||
curCamera.GetComponent<Camera>().fieldOfView = (float)cameraToFOV;
|
||
if(isScEditorCameraMoving)
|
||
{
|
||
isScEditorCameraMoving = false;
|
||
//man.mouseEnterUI();
|
||
}
|
||
else
|
||
{
|
||
playMode = "play";
|
||
PlayActs();
|
||
}
|
||
|
||
}
|
||
//curCamera.AddComponent<forCamera>();
|
||
//Debug.Log("time = " + cameraMoveCurTime + " / "+cameraMoveMaxTime + ", d = " + d + " camera cur: " + curCamera.transform.position.x + " " + curCamera.transform.position.y + " " + curCamera.transform.position.z);
|
||
//Debug.Log(" from: " + cameraIsMovingFromPos.position.x + " " + cameraIsMovingFromPos.position.y + " " + cameraIsMovingFromPos.position.z);
|
||
}
|
||
}
|
||
|
||
public void LoadScenario(string scName)
|
||
{
|
||
//Debug.LogError("Loading Scenario " + scName);
|
||
if (man == null)
|
||
Init();
|
||
if (scName == "") return;
|
||
StartCoroutine(LoadCoroutine(scName));
|
||
}
|
||
|
||
public IEnumerator LoadCoroutine(string scName)
|
||
{
|
||
//Debug.Log("Starting Player.LoadCoroutine.");
|
||
while (!man.isInitiated)
|
||
yield return null;
|
||
|
||
if (scName.ToLower() == "freemode")
|
||
{
|
||
man.mode = "free"; man.viewmode = 1;
|
||
man.menuPlayButtons.SetActive(false);
|
||
man.switchModeFree();
|
||
man.ChangeLayerPilotCabineDefault();
|
||
man.ChangeLayerExternalPanelsIgnore();
|
||
man.ChangeLayerPassCabineIgnore();
|
||
GameObject.Find("Air/view1").GetComponent<hintUI>().Start();
|
||
GameObject.Find("Air/view1").GetComponent<hintUI>().OnPointerDown(null);
|
||
GameObject.Find("Air/view1").GetComponent<Return2Cabin>().OnPointerClick(null);
|
||
man.mouseExitUI();
|
||
yield break;
|
||
}
|
||
if (scName.ToLower().StartsWith("system_"))
|
||
{
|
||
man.switchModeView();
|
||
man.menuPlayButtons.SetActive(false);
|
||
GameObject.Find("Air").SetActive(false);
|
||
GameObject.Find("Obzor").GetComponent<ChangeSystem>().ChooseSys(scName);
|
||
yield break;
|
||
}
|
||
|
||
SC = null; state = "empty";
|
||
btnPlay.SetActive(true); btnPause.SetActive(false);
|
||
actCounterText.GetComponent<Text>().text = "";
|
||
canProgressBarChangePos = false; progressBar.GetComponent<Slider>().value = 0; canProgressBarChangePos = true;
|
||
//Debug.Log("Loading Scenario: StartCoroutine");
|
||
|
||
if (!scName.ToLower().EndsWith(".xml"))
|
||
scName += ".xml";
|
||
string path = Path.Combine(Application.streamingAssetsPath, "Scenario", scName); //+".xml"
|
||
bool isWeb;
|
||
string scText = "";
|
||
|
||
if(man == null)
|
||
man = GameObject.Find("Manager").GetComponent<Manager>();
|
||
Transform[] allPanels2D = man.canvas.transform.GetChild(0).GetComponentsInChildren<Transform>();
|
||
Transform[] allPanels3D = man.copter.GetComponentsInChildren<Transform>();
|
||
|
||
//Debug.Log("Player: Trying Deserialize " + path);
|
||
path = path.Replace("file:///", "");
|
||
|
||
if (path.Contains("http"))
|
||
{
|
||
UnityWebRequest www = UnityWebRequest.Get(path);
|
||
www.downloadHandler = new DownloadHandlerBuffer();
|
||
yield return www.SendWebRequest();
|
||
|
||
if (www.result == UnityWebRequest.Result.ConnectionError || www.result == UnityWebRequest.Result.ProtocolError)
|
||
{
|
||
Debug.LogError(www.error);
|
||
yield break;
|
||
}
|
||
else
|
||
{
|
||
scText = www.downloadHandler.text;
|
||
//Debug.LogError("Player Web Deserialize: downloaded bytes " + scText.Length);
|
||
}
|
||
isWeb = true;
|
||
}
|
||
else
|
||
isWeb = false;
|
||
|
||
if (!isWeb && Application.platform == RuntimePlatform.WebGLPlayer)
|
||
{
|
||
//Debug.LogError("Player: Cannot open local files in WebGL");
|
||
}
|
||
else
|
||
{
|
||
var utf8 = Encoding.UTF8 as UTF8Encoding;
|
||
XmlSerializer serializer = new XmlSerializer(typeof(Scenario));
|
||
Stream fs;
|
||
if (isWeb)
|
||
fs = new MemoryStream(utf8.GetBytes(scText));
|
||
else
|
||
fs = new FileStream(path, FileMode.Open);
|
||
XmlReader reader = new XmlTextReader(fs);
|
||
bool res = serializer.CanDeserialize(reader);
|
||
reader.Close();
|
||
fs.Close();
|
||
|
||
if (!res)
|
||
yield break;
|
||
|
||
if (isWeb)
|
||
fs = new MemoryStream(utf8.GetBytes(scText));
|
||
else
|
||
fs = new FileStream(path, FileMode.Open);
|
||
SC = (Scenario)serializer.Deserialize(fs);
|
||
//Debug.LogError("Player Deserialize: man.objects = " + man.objects.obj.Count);
|
||
fs.Close();
|
||
}
|
||
SC.name = scName;
|
||
if (SC == null)
|
||
{
|
||
Debug.LogError("Player: Scenario loading error (" + path + ")");
|
||
yield break;
|
||
}
|
||
else
|
||
Debug.Log("Player: Loaded " + SC.init.acts.Count + " init, " + SC.demo.acts.Count + " demo, " + SC.train.acts.Count + " train, " + SC.exam.acts.Count + " exam" + " action(s) from " + path);
|
||
|
||
//Debug.LogError("Player: Loaded " + SC.init.acts.Count + " init, " + SC.demo.acts.Count + " demo, " + SC.train.acts.Count + " train, " + SC.exam.acts.Count + " exam" + " action(s) from " + path);
|
||
|
||
if (SC == null)
|
||
{
|
||
state = "empty";
|
||
actCounterText.GetComponent<Text>().text = "Сценарий не загружен";
|
||
}
|
||
else
|
||
{
|
||
if (btnDemoMode == null) btnDemoMode = GameObject.Find("DemoMenuButton");
|
||
if (btnTrainMode == null) btnTrainMode = GameObject.Find("LearnMenuButton");
|
||
if (btnExamMode == null) btnExamMode = GameObject.Find("TestMenuButton");
|
||
|
||
btnDemoMode.GetComponent<hintUI>().Start();
|
||
btnTrainMode.GetComponent<hintUI>().Start();
|
||
btnExamMode.GetComponent<hintUI>().Start();
|
||
|
||
btnDemoMode.GetComponent<hintUI>().enabled = (SC.demo.acts.Count > 0);
|
||
Image[] img = btnDemoMode.GetComponentsInChildren<Image>();
|
||
for (var i = 0; i < img.Length; i++)
|
||
img[i].color = (SC.demo.acts.Count > 0) ? Color.white : Color.gray;
|
||
if(img.Length == 2 && SC.demo.acts.Count == 0)
|
||
{ img[0].gameObject.SetActive(true); img[1].gameObject.SetActive(false); }
|
||
|
||
btnTrainMode.GetComponent<hintUI>().enabled = (SC.train.acts.Count > 0);
|
||
img = btnTrainMode.GetComponentsInChildren<Image>();
|
||
for (int i = 0; i < img.Length; i++)
|
||
img[i].color = (SC.train.acts.Count > 0) ? Color.white : Color.gray;
|
||
if (img.Length == 2 && SC.train.acts.Count == 0)
|
||
{ img[0].gameObject.SetActive(true); img[1].gameObject.SetActive(false); }
|
||
|
||
btnExamMode.GetComponent<hintUI>().enabled = (SC.exam.acts.Count > 0);
|
||
img = btnExamMode.GetComponentsInChildren<Image>();
|
||
for (var i = 0; i < img.Length; i++)
|
||
img[i].color = (SC.exam.acts.Count > 0) ? Color.white : Color.gray;
|
||
if (img.Length == 2 && SC.exam.acts.Count == 0)
|
||
{ img[0].gameObject.SetActive(true); img[1].gameObject.SetActive(false); }
|
||
|
||
if (SC.demo.acts.Count > 0)
|
||
SetMode("demo");
|
||
else
|
||
if (SC.train.acts.Count > 0)
|
||
SetMode("train");
|
||
else
|
||
if (SC.exam.acts.Count > 0)
|
||
SetMode("exam");
|
||
|
||
if(man.mode == "play")
|
||
{
|
||
playerText.transform.Find("PlayerTextTMP").gameObject.GetComponent<TMP_Text>().text = "Загружен сценарий \""+SC.title+ "\".\n<br><alpha=#AA>Выберите режим Демонстрация, Обучение или Контроль и нажмите кнопку воспроизведения.";
|
||
playerText.SetActive(true);
|
||
}
|
||
if (SC.needExamCompleted && SC.exam != null && SC.exam.acts != null && SC.exam.acts.Count > 0 && Application.platform == RuntimePlatform.WebGLPlayer)
|
||
{
|
||
//Application.ExternalCall("scLoaded", SC.name, SC.title);
|
||
}
|
||
else
|
||
{
|
||
if (Application.platform == RuntimePlatform.WebGLPlayer)
|
||
Application.ExternalCall("scFinished", SC.name, SC.title);
|
||
}
|
||
|
||
}
|
||
//Debug.Log("Done Player.LoadCoroutine.");
|
||
}
|
||
|
||
public void SetMode(string newmode)
|
||
{
|
||
//Debug.Log("Player: SetMode "+newmode);
|
||
if (newmode == "demo" && SC.demo.acts.Count == 0) return;
|
||
if (newmode == "train" && SC.train.acts.Count == 0) return;
|
||
if (newmode == "exam" && SC.exam.acts.Count == 0) return;
|
||
for (int i = 0; i < highlightList.Count; i++)
|
||
{
|
||
RemoveFromHighliteList(highlightList[i].obj.name);
|
||
i--;
|
||
}
|
||
state = "ready";
|
||
mode = newmode;
|
||
Build();
|
||
state = "pause"; nextAct = 0;
|
||
btnDemoMode.GetComponent<hintUI>().isGreen = (newmode == "demo"); btnDemoMode.GetComponent<hintUI>().OnPointerUp(null);
|
||
btnTrainMode.GetComponent<hintUI>().isGreen = (newmode == "train"); btnTrainMode.GetComponent<hintUI>().OnPointerUp(null);
|
||
btnExamMode.GetComponent<hintUI>().isGreen = (newmode == "exam"); btnExamMode.GetComponent<hintUI>().OnPointerUp(null);
|
||
if (newmode == "exam" && man.mode == "play")
|
||
progressBar.GetComponent<Slider>().enabled = false;
|
||
else
|
||
progressBar.GetComponent<Slider>().enabled = true;
|
||
//actCounterText.GetComponent<Text>().text = "";
|
||
btnPlay.SetActive(true); btnPause.SetActive(false);
|
||
if (!man.is3D) man.SwitchTo3D();
|
||
man.objects.SetDefaultValues();
|
||
if(man.mode == "play")
|
||
man.mouseEnterUI();
|
||
man.mfi1.ses = man.mfi2.ses = man.mfi3.ses = man.mfi4.ses = man.mfi5.ses = true;
|
||
}
|
||
|
||
public void Play()
|
||
{
|
||
//Debug.Log("Player: play");
|
||
btnPlay.SetActive(true); btnPause.SetActive(false);
|
||
if (!man.is3D && state != "pause")
|
||
man.SwitchTo3D();
|
||
if (state == "empty" || SC == null)
|
||
{
|
||
//Debug.Log("Scenario not loaded.");
|
||
actCounterText.GetComponent<Text>().text = "Сценарий не загружен";
|
||
return;
|
||
}
|
||
if (state == "ready")
|
||
{
|
||
Build();
|
||
man.mfi1.ses = man.mfi2.ses = man.mfi3.ses = man.mfi4.ses = man.mfi5.ses = true;
|
||
}
|
||
state = "play"; playMode = "play";
|
||
btnPlay.SetActive(false); btnPause.SetActive(true);
|
||
playerText.SetActive(false);
|
||
|
||
if(sce != null && sce.isActiveAndEnabled)
|
||
sce.SetDefaultMaterialsToCurrentObject();
|
||
//InvokeRepeating("HighliteRefresh", 0, highlightTimeDelta);
|
||
//Debug.Log("Player.Play: InvokeRepeating setStateInTime");
|
||
CancelInvoke("setStateInTime");
|
||
InvokeRepeating("setStateInTime", 0, setStateInTimeDelta);
|
||
//Debug.Log("Player.Play: InvokeRepeating PlayActs");
|
||
CancelInvoke("PlayActs");
|
||
InvokeRepeating("PlayActs", 0, playDelta); // CancelInvoke ("PlayActs")
|
||
}
|
||
|
||
public void Pause()
|
||
{
|
||
//Debug.Log("Player: pause");
|
||
if (playMode == "waitForClick") return;
|
||
state = "pause";
|
||
btnPlay.SetActive(true); btnPause.SetActive(false);
|
||
//Debug.Log("Player.Pause: CancelInvoke setStateInTime");
|
||
//Debug.Log("Player.Pause: CancelInvoke PlayActs");
|
||
CancelInvoke("PlayActs");
|
||
CancelInvoke("setStateInTime");
|
||
//CancelInvoke("HighliteRefresh");
|
||
}
|
||
|
||
void PlayActs()
|
||
{
|
||
if (buildInProgress) return; // ждем окончания работы корутины
|
||
if (state != "play") return;
|
||
if (playMode == "waitForClick") return;
|
||
if (playMode == "cameraIsMoving") return;
|
||
if (playMode == "waitForTime") // play, waitForTime, waitForClick
|
||
{
|
||
playTimeToWait -= playDelta;
|
||
if (playTimeToWait > 0) return;
|
||
playMode = "play"; playTimeToWait = 0;
|
||
}
|
||
|
||
if (nextAct >= acts.Count)
|
||
{
|
||
ScenarioFinished();
|
||
return;
|
||
}
|
||
|
||
while (state == "play" && playMode == "play")
|
||
{
|
||
canProgressBarChangePos = false; progressBar.GetComponent<Slider>().value = nextAct; canProgressBarChangePos = true;
|
||
|
||
int actsDone = nextAct - 1; if (actsDone < 0) actsDone = 0;
|
||
actCounterText.GetComponent<Text>().text = acts[actsDone].actNumberToShow + "/" + acts[acts.Count - 1].actNumberToShow;
|
||
RunAction(acts[nextAct]);
|
||
|
||
nextAct++; //последний плохо работает
|
||
if (nextAct >= acts.Count && playMode != "waitForClick" && playMode != "waitForTime" && playMode != "cameraIsMoving")
|
||
ScenarioFinished();
|
||
}
|
||
|
||
}
|
||
// setState, setStateInRange, openPanel, setTextField, setIntField, switchTo3D, highlightOn, highlightOff,
|
||
// highlightTime, waitForClick, waitForTime, setCurCameraPos, showText, hideText, execScenario, playAudio
|
||
public void RunAction(ScAction act, bool runFast=false)
|
||
{
|
||
//Debug.Log(" Play " + nextAct + ": " + act.type);
|
||
if(act.type == "setState")
|
||
{
|
||
UnityObject obj = man.objects.Find(act.objName);
|
||
if(obj == null)
|
||
{
|
||
ScenarioError("Ошибка setState: объект \"" + act.objName + "\" не найден в сцене.");
|
||
state = "pause";
|
||
return;
|
||
}
|
||
SetObjectState(obj, act.setState.val);
|
||
}
|
||
if (act.type == "setStateInRange")
|
||
{
|
||
UnityObject obj = man.objects.Find(act.objName);
|
||
if (obj == null)
|
||
{
|
||
ScenarioError("Ошибка setStateInRange: объект \"" + act.objName + "\" не найден в сцене.");
|
||
state = "pause";
|
||
return;
|
||
}
|
||
if(!runFast)
|
||
SetObjectState(obj, act.setStateInRange.val, act.setStateInRange.sec);
|
||
else
|
||
SetObjectState(obj, act.setStateInRange.val, 0);
|
||
}
|
||
if (act.type == "openPanel")
|
||
{
|
||
if (act.objName.Substring(act.objName.Length - 3) == "_3D")
|
||
{
|
||
string panel2D = act.objName.Substring(0, act.objName.Length - 3);
|
||
UnityObject obj2D = man.objects.Find(panel2D);
|
||
if (obj2D != null)
|
||
man.SwitchTo2D(obj2D.name);
|
||
else
|
||
{
|
||
ScenarioError("Ошибка сценария: соответствующая объекту \""+ act.objName + "\" 2D-панель не найдена.");
|
||
state = "pause";
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ScenarioError("Ошибка сценария: невозможно определить имя 2D-панели объекта \"" + act.objName + "\".");
|
||
state = "pause";
|
||
return;
|
||
}
|
||
}
|
||
if (act.type == "switchTo3D")
|
||
{
|
||
if(man.is3D)
|
||
{
|
||
ScenarioError("Ошибка сценария: действие \"Закрыть панель\" невыполнимо - нет открытых панелей.");
|
||
state = "pause";
|
||
return;
|
||
}
|
||
man.SwitchTo3D();
|
||
}
|
||
if (act.type == "setTextField")
|
||
{
|
||
UnityObject obj = man.objects.Find(act.objName);
|
||
if (obj == null)
|
||
{
|
||
ScenarioError("Ошибка setTextField: объект \"" + act.objName + "\" не найден в сцене.");
|
||
state = "pause";
|
||
return;
|
||
}
|
||
obj.SetObjectText(act.setTextField.text, act.setTextField.color);
|
||
}
|
||
if (act.type == "setIntField" || act.type == "setFloatField")
|
||
{
|
||
UnityObject obj = man.objects.Find(act.objName);
|
||
if (obj == null)
|
||
{
|
||
ScenarioError("Ошибка setIntField: объект \"" + act.objName + "\" не найден в сцене.");
|
||
state = "pause";
|
||
return;
|
||
}
|
||
obj.textcolor = act.setIntField.color;
|
||
obj.setTextFieldAsFloat = (act.type == "setFloatField");
|
||
if (!runFast)
|
||
{
|
||
SetObjectState(obj, act.setIntField.valFrom, 0);
|
||
SetObjectState(obj, act.setIntField.valTo, act.setIntField.sec);
|
||
}
|
||
else
|
||
SetObjectState(obj, act.setIntField.valTo, 0);
|
||
}
|
||
|
||
if (act.type == "highlightOn")
|
||
{
|
||
AddToHighliteList(act.objName);
|
||
}
|
||
if (act.type == "highlightOff")
|
||
{
|
||
RemoveFromHighliteList(act.objName);
|
||
}
|
||
if (act.type == "highlightTime")
|
||
{
|
||
AddToHighliteList(act.objName, act.highlightTime.sec);
|
||
}
|
||
|
||
if (act.type == "waitForClick" && !runFast)
|
||
{
|
||
waitForClickObjName = act.objName;
|
||
playMode = "waitForClick";
|
||
if (man.mode == "play")
|
||
man.mouseExitUI();
|
||
}
|
||
|
||
if (act.type == "waitForTime")
|
||
{
|
||
if (!runFast)
|
||
{
|
||
playMode = "waitForTime";
|
||
playTimeToWait = act.waitForTime.sec;
|
||
}
|
||
else
|
||
{
|
||
for (int k = 0; k < highlightList.Count; k++)
|
||
{
|
||
highlightObj hObj = highlightList[k];
|
||
if (hObj.sec != 0f)
|
||
{
|
||
hObj.sec -= act.waitForTime.sec;
|
||
if (hObj.sec <= 0)
|
||
{
|
||
RemoveFromHighliteList(hObj.obj.name);
|
||
k--; continue;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
if (act.type == "showText")
|
||
{
|
||
playerText.transform.Find("PlayerTextTMP").gameObject.GetComponent<TMP_Text>().text = act.showText.text;
|
||
playerText.SetActive(true);
|
||
}
|
||
if (act.type == "hideText")
|
||
{
|
||
playerText.SetActive(false);
|
||
}
|
||
|
||
//if (act.type == "execScenario") не нужно
|
||
if (act.type == "playAudio" && !runFast)
|
||
{
|
||
AudioSource aSrc = GameObject.Find("audioPlayer").GetComponent<AudioSource>();
|
||
aSrc.clip = act.playAudio.clip;
|
||
aSrc.Play();
|
||
}
|
||
|
||
if (act.type == "switchMFIScreen")
|
||
{
|
||
man.objects.Find(act.objName).gameObject.GetComponent<MFIScript>().SwitchScreen(act.switchMFIScreen.scrName);
|
||
}
|
||
if (act.type == "setSkybox")
|
||
{
|
||
GameObject.Find("skyBox").GetComponent<ChangeSkybox>().setSkybox(act.setSkybox.name);
|
||
}
|
||
if (act.type == "showRect")
|
||
{
|
||
rectsList.Add(act.showRect);
|
||
isRectsShowing = true;
|
||
}
|
||
if (act.type == "hideRects")
|
||
{
|
||
rectsList.Clear();
|
||
isRectsShowing = false;
|
||
}
|
||
|
||
if (act.type == "setCurCameraPos" && !runFast)
|
||
{
|
||
if (!man.is3D && !isScEditorCameraMoving)
|
||
{
|
||
ScenarioError("Ошибка сценария: для перемещения камеры необходимо закрыть 2D-панель.");
|
||
state = "pause";
|
||
return;
|
||
//man.SwitchTo3D();
|
||
//man.ChangeLayerDefault(); !!!
|
||
}
|
||
|
||
playCamera = act.setCurCameraPos.camera;
|
||
if (playCamera == "cabin")
|
||
{
|
||
curCamera = man.cabinCamera;
|
||
man.switchModeFree();
|
||
if (act.setCurCameraPos.position.z > 6.15f)
|
||
{ // кабина
|
||
man.viewmode = 1;
|
||
curCamera.GetComponent<Camera>().farClipPlane = 100f;
|
||
curCamera.GetComponent<Camera>().fieldOfView = 50f; //60f;
|
||
man.ChangeLayerExternalPanelsIgnore();
|
||
man.ChangeLayerPilotCabineDefault();
|
||
man.ChangeLayerPassCabineIgnore();
|
||
}
|
||
else
|
||
{ // грузовая
|
||
man.viewmode = 2;
|
||
curCamera.GetComponent<Camera>().farClipPlane = 200f;
|
||
curCamera.GetComponent<Camera>().fieldOfView = 50f;
|
||
man.ChangeLayerExternalPanelsIgnore();
|
||
man.ChangeLayerPassCabineDefault();
|
||
man.ChangeLayerPilotCabineIgnore();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
man.viewmode = 3;
|
||
curCamera = man.viewCamera;
|
||
man.switchModeView();
|
||
}
|
||
cameraIsMovingToPos.position = act.setCurCameraPos.position.toVector3(); cameraIsMovingToPos.rotation = act.setCurCameraPos.rotation.toQuaternion();
|
||
cameraIsMovingFromPos.position = curCamera.transform.position; cameraIsMovingFromPos.rotation = curCamera.transform.rotation;
|
||
|
||
cameraMoveCurTime = 0;
|
||
var heading = cameraIsMovingToPos.position - curCamera.transform.position;
|
||
cameraMoveMaxTime = 1f;
|
||
int dist = (int)((float)heading.magnitude * act.setCurCameraPos.scale.x);
|
||
if (dist <= 1) cameraMoveMaxTime = 1f;
|
||
if (dist > 1 && dist <= 3) cameraMoveMaxTime = 1.9f;
|
||
if (dist > 3 && dist <= 8) cameraMoveMaxTime = 2.7f;
|
||
if (dist > 8) cameraMoveMaxTime = 3.5f;
|
||
|
||
if (playCamera == "cabin")
|
||
{
|
||
cameraFromFOV = (int)curCamera.GetComponent<Camera>().fieldOfView;
|
||
cameraToFOV = (int)act.setCurCameraPos.fov;
|
||
if (cameraToFOV > cameraFromFOV)
|
||
curCamera.GetComponent<Camera>().fieldOfView = (float)cameraToFOV;
|
||
}
|
||
else
|
||
{
|
||
cameraIsMovingToPos.scale = act.setCurCameraPos.scriptOffset.toVector3(); // переменные скрипта внешней камеры, это не scale
|
||
cameraIsMovingFromPos.scale = curCamera.GetComponent<CameraFree>().offset;
|
||
curCamera.GetComponent<CameraFree>().offset = act.setCurCameraPos.scriptOffset.toVector3();
|
||
//curCamera.GetComponent<CameraFree>().offset.y = act.setCurCameraPos.scriptOffset.y;
|
||
//curCamera.GetComponent<CameraFree>().offset.z = act.setCurCameraPos.scriptOffset.z;
|
||
}
|
||
man.viewmode = act.setCurCameraPos.viewMode;
|
||
playMode = "cameraIsMoving";
|
||
}
|
||
|
||
}
|
||
|
||
void setStateInTime()
|
||
{
|
||
for(int i=0;i<setStateInTimeList.Count;i++)
|
||
{
|
||
int newstate = (int)Mathf.Round(Mathf.Lerp((float)setStateInTimeList[i].fromState, (float)setStateInTimeList[i].toState, setStateInTimeList[i].runCurTime / setStateInTimeList[i].runTime));
|
||
if (newstate != setStateInTimeList[i].obj.curState)
|
||
setStateInTimeList[i].obj.SetObjectState(newstate);
|
||
|
||
setStateInTimeList[i].runCurTime += setStateInTimeDelta;
|
||
if(setStateInTimeList[i].runCurTime >= setStateInTimeList[i].runTime)
|
||
{
|
||
setStateInTimeList[i].obj.SetObjectState(setStateInTimeList[i].toState);
|
||
setStateInTimeList.RemoveAt(i); i--;
|
||
}
|
||
}
|
||
}
|
||
|
||
public void SetObjectState(UnityObject obj, int newState, float sec = 0) // функция для обработки изменений состояния за определенное время
|
||
{ // непосредственное изменение - в классе Mi38objects - obj.SetObjectState(newState);
|
||
// (класс Mi38objects не является наследником MonoBehaviour и не позволяет вызывать корутины и т.п.)
|
||
if (obj.dim == "2D" && obj.type == "buttonAutoUncheck")
|
||
{
|
||
obj.SetObjectState(newState);
|
||
if(newState == 1)
|
||
{
|
||
buttonAutoUncheckList.Add(obj);
|
||
Invoke("button2DAutoUncheckFunction", 0.5f);
|
||
}
|
||
return;
|
||
}
|
||
|
||
if(sec == 0)
|
||
obj.SetObjectState(newState); // для всех остальных случаев
|
||
else
|
||
{
|
||
setStateInTimeStruct sit = new setStateInTimeStruct();
|
||
sit.obj = obj; sit.runCurTime = 0; sit.runTime = sec;
|
||
sit.fromState = obj.curState; sit.toState = newState;
|
||
setStateInTimeList.Add(sit);
|
||
}
|
||
|
||
}
|
||
void button2DAutoUncheckFunction()
|
||
{
|
||
foreach(UnityObject obj in buttonAutoUncheckList)
|
||
obj.SetObjectState(0);
|
||
buttonAutoUncheckList.Clear();
|
||
}
|
||
|
||
void ScenarioFinished()
|
||
{
|
||
//Debug.Log("Player.ScenarioFinished: CancelInvoke setStateInTime"); Debug.Log("Player.ScenarioFinished: CancelInvoke PlayActs");
|
||
CancelInvoke("PlayActs"); CancelInvoke("setStateInTime"); //CancelInvoke("HighliteRefresh");
|
||
rectsList.Clear(); isRectsShowing = false;
|
||
man.mfi1.ses = man.mfi2.ses = man.mfi3.ses = man.mfi4.ses = man.mfi5.ses = true;
|
||
state = "pause"; nextAct = 0;
|
||
int actsDone = nextAct - 1; if (actsDone < 0) actsDone = 0;
|
||
actCounterText.GetComponent<Text>().text = acts[actsDone].actNumberToShow + "/" + acts[acts.Count-1].actNumberToShow;
|
||
canProgressBarChangePos = false; progressBar.GetComponent<Slider>().value = 0; canProgressBarChangePos = true;
|
||
btnPlay.SetActive(true); btnPause.SetActive(false);
|
||
AudioSource aSrc = GameObject.Find("audioPlayer").GetComponent<AudioSource>();
|
||
aSrc.Stop();
|
||
man.objects.SetDefaultValues();
|
||
for(int i=0;i<highlightList.Count;i++)
|
||
RemoveFromHighliteList(highlightList[0].obj.name);
|
||
//highlightList.Clear();
|
||
// сценарий завершен, вывести сообщение?
|
||
string text = "Выполнение сценария в режиме \"";
|
||
if (mode == "demo") text += "Демонстрация";
|
||
if (mode == "train") text += "Обучение";
|
||
if (mode == "exam") text += "Контроль";
|
||
text += "\" завершено.";
|
||
if (mode == "exam")
|
||
{
|
||
text += "\n<color=#00aa00>Вы можете продолжить изучение материала курса.</color>";
|
||
// отправляем сообщение на страницу об успешном завершении
|
||
if (Application.platform == RuntimePlatform.WebGLPlayer)
|
||
Application.ExternalCall("scFinished", SC.name, SC.title);
|
||
}
|
||
else
|
||
{
|
||
if (SC.needExamCompleted)
|
||
text += "\nДля изучения темы установлено обязательное выполнение режима \"Контроль\".";
|
||
}
|
||
ScenarioMsg5sec(text);
|
||
}
|
||
|
||
public void Build()
|
||
{
|
||
if (buildInProgress) return;
|
||
//Debug.Log("Player: build");
|
||
acts.Clear();
|
||
for (int i = 0; i < highlightList.Count; i++)
|
||
{
|
||
RemoveFromHighliteList(highlightList[i].obj.name);
|
||
i--;
|
||
}
|
||
rectsList.Clear(); isRectsShowing = false;
|
||
curScMode = null;
|
||
if (mode == "demo") curScMode = SC.demo;
|
||
if (mode == "train") curScMode = SC.train;
|
||
if (mode == "exam") curScMode = SC.exam;
|
||
if (curScMode == null) return;
|
||
StartCoroutine(BuildCourotine());
|
||
}
|
||
|
||
public IEnumerator BuildCourotine()
|
||
{
|
||
buildInProgress = true;
|
||
|
||
yield return buildScMode(SC.init);
|
||
yield return buildScMode(curScMode, true);
|
||
int curActNumToShow = 0;
|
||
for (int i = 0; i < acts.Count; i++)
|
||
if (acts[i].actNumberToShow == -1)
|
||
acts[i].actNumberToShow = curActNumToShow;
|
||
else
|
||
curActNumToShow = acts[i].actNumberToShow;
|
||
|
||
nextAct = 0;
|
||
int actsDone = nextAct - 1; if (actsDone < 0) actsDone = 0;
|
||
actCounterText.GetComponent<Text>().text = acts[actsDone].actNumberToShow + "/" + acts[acts.Count - 1].actNumberToShow;
|
||
if (acts.Count != 0)
|
||
progressBar.GetComponent<Slider>().maxValue = acts.Count-1;
|
||
canProgressBarChangePos = false; progressBar.GetComponent<Slider>().value = 0; canProgressBarChangePos = true;
|
||
man.objects.SetDefaultValues();
|
||
buildInProgress = false;
|
||
//Debug.Log("Player: builded " + acts.Count + " total actions");
|
||
|
||
IEnumerator buildScMode(ScenarioMode scMode, bool showActNumber=false)
|
||
{
|
||
for (int i = 0; i < scMode.acts.Count; i++)
|
||
{
|
||
if (scMode.acts[i].type != "execScenario" && scMode.acts[i].type != "playAudio")
|
||
acts.Add(scMode.acts[i].clone());
|
||
if (scMode.acts[i].type == "execScenario")
|
||
{
|
||
actCounterText.GetComponent<Text>().text = "Загрузка сценария " + scMode.acts[i].execScenario.name;
|
||
yield return StartCoroutine(BuildActExecScenario(scMode.acts[i]));
|
||
}
|
||
if (scMode.acts[i].type == "playAudio")
|
||
{
|
||
actCounterText.GetComponent<Text>().text = "Загрузка аудио " + scMode.acts[i].playAudio.filename;
|
||
yield return StartCoroutine(BuildActPlayAudio(scMode.acts[i]));
|
||
}
|
||
if (showActNumber)
|
||
acts[acts.Count - 1].actNumberToShow = i + 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
public IEnumerator BuildActExecScenario(ScAction execAct)
|
||
{
|
||
string path = Path.Combine(Application.streamingAssetsPath, "Scenario", execAct.execScenario.name + ".xml");
|
||
string scText = "";
|
||
|
||
UnityWebRequest www = UnityWebRequest.Get(path);
|
||
www.downloadHandler = new DownloadHandlerBuffer();
|
||
yield return www.SendWebRequest();
|
||
if (www.result == UnityWebRequest.Result.ConnectionError || www.result == UnityWebRequest.Result.ProtocolError)
|
||
{
|
||
Debug.LogError("Player: error loading scenario ("+ path + ")" + www.error);
|
||
yield break;
|
||
}
|
||
else
|
||
scText = www.downloadHandler.text;
|
||
var utf8 = Encoding.UTF8 as UTF8Encoding;
|
||
XmlSerializer serializer = new XmlSerializer(typeof(Scenario));
|
||
Stream fs = new MemoryStream(utf8.GetBytes(scText));
|
||
XmlReader reader = new XmlTextReader(fs);
|
||
bool res = serializer.CanDeserialize(reader);
|
||
reader.Close(); fs.Close();
|
||
if (!res)
|
||
yield break;
|
||
fs = new MemoryStream(utf8.GetBytes(scText));
|
||
|
||
Scenario execSC = (Scenario)serializer.Deserialize(fs);
|
||
//Debug.LogError("Player Deserialize: man.objects = " + man.objects.obj.Count);
|
||
fs.Close();
|
||
|
||
if (execSC == null)
|
||
Debug.LogError("Player exec scenario: Scenario loading error (" + path + ")");
|
||
//else
|
||
// Debug.Log("Player exec scenario: Loaded " + execSC.init.acts.Count + " init, " + execSC.demo.acts.Count + " demo, " + execSC.train.acts.Count + " train, " + execSC.exam.acts.Count + " exam" + " action(s) from " + path);
|
||
|
||
ScenarioMode execCurScMode = execSC.demo;
|
||
if (mode == "train") execCurScMode = execSC.train;
|
||
if (mode == "exam") execCurScMode = execSC.exam;
|
||
|
||
yield return buildExecScMode(execSC.init);
|
||
yield return buildExecScMode(execCurScMode);
|
||
|
||
IEnumerator buildExecScMode(ScenarioMode scMode)
|
||
{
|
||
for (int i = 0; i < scMode.acts.Count; i++)
|
||
{
|
||
if (scMode.acts[i].type == "openPanel" || scMode.acts[i].type == "switchTo3D" || scMode.acts[i].type == "highlightOn" || scMode.acts[i].type == "highlightOff" ||
|
||
scMode.acts[i].type == "highlightTime" || scMode.acts[i].type == "waitForClick" || scMode.acts[i].type == "setCurCameraPos" || scMode.acts[i].type == "showText" ||
|
||
scMode.acts[i].type == "hideText" || scMode.acts[i].type == "playAudio")
|
||
if (execAct.execScenario.fastFlag) continue;
|
||
|
||
if (scMode.acts[i].type == "execScenario")
|
||
{
|
||
actCounterText.GetComponent<Text>().text = "Загрузка сценария " + scMode.acts[i].execScenario.name;
|
||
if (execAct.execScenario.fastFlag)
|
||
scMode.acts[i].execScenario.fastFlag = true;
|
||
yield return StartCoroutine(BuildActExecScenario(scMode.acts[i]));
|
||
continue;
|
||
}
|
||
if (scMode.acts[i].type == "playAudio")
|
||
{
|
||
actCounterText.GetComponent<Text>().text = "Загрузка аудио " + scMode.acts[i].playAudio.filename;
|
||
yield return StartCoroutine(BuildActPlayAudio(scMode.acts[i]));
|
||
continue;
|
||
}
|
||
if (scMode.acts[i].type == "setStateInRange")
|
||
{
|
||
if (execAct.execScenario.fastFlag)
|
||
scMode.acts[i].setStateInRange.sec = 0;
|
||
}
|
||
if (scMode.acts[i].type == "setIntField" || scMode.acts[i].type == "setFloatField")
|
||
{
|
||
if (execAct.execScenario.fastFlag)
|
||
scMode.acts[i].setIntField.sec = 0;
|
||
}
|
||
|
||
acts.Add(scMode.acts[i].clone());
|
||
}
|
||
}
|
||
}
|
||
// setState, setStateInRange, openPanel, setTextField, setIntField, switchTo3D, highlightOn, highlightOff,
|
||
// highlightTime, waitForClick, waitForTime, setCurCameraPos, showText, hideText, execScenario, playAudio
|
||
|
||
public IEnumerator BuildActPlayAudio(ScAction playAct)
|
||
{
|
||
//Debug.Log("Player: build ActPlay " + playAct.playAudio.filename);
|
||
string path = Path.Combine(Application.streamingAssetsPath, "Scenario", SC.name.Replace(".xml",""), playAct.playAudio.filename);
|
||
|
||
UnityWebRequest www;
|
||
if(playAct.playAudio.filename.EndsWith(".wav"))
|
||
www = UnityWebRequestMultimedia.GetAudioClip(path, AudioType.WAV);
|
||
else
|
||
www = UnityWebRequestMultimedia.GetAudioClip(path, AudioType.MPEG);
|
||
yield return www.SendWebRequest();
|
||
|
||
if (www.result == UnityWebRequest.Result.ConnectionError || www.result == UnityWebRequest.Result.ProtocolError)
|
||
{
|
||
Debug.LogError("Player: error loading audio - "+ www.error+ " " + path);
|
||
playAct.playAudio.clip = null;
|
||
yield break;
|
||
}
|
||
else
|
||
{
|
||
playAct.playAudio.clip = DownloadHandlerAudioClip.GetContent(www);
|
||
//Debug.Log("Player audio from Web: downloaded seconds " + playAct.playAudio.clip.length);
|
||
}
|
||
|
||
ScAction res = playAct.clone();
|
||
res.playAudio.clip = playAct.playAudio.clip;
|
||
acts.Add(res);
|
||
}
|
||
|
||
|
||
public void onProgressBarChange()
|
||
{
|
||
if (state == "empty") // || state == "ready"
|
||
return;
|
||
if (!canProgressBarChangePos)
|
||
return;
|
||
if (man.isProgressBarChangingInProgress) return;
|
||
|
||
//Debug.Log("Player: onProgressBarChange");
|
||
state = "pause";
|
||
btnPlay.SetActive(true); btnPause.SetActive(false);
|
||
int toAct = (int)progressBar.GetComponent<Slider>().value;
|
||
|
||
if (progressBar.GetComponent<Slider>().value == 0f)
|
||
{
|
||
man.objects.SetDefaultValues();
|
||
actCounterText.GetComponent<Text>().text = "0/" + acts[acts.Count - 1].actNumberToShow;
|
||
}
|
||
else
|
||
actCounterText.GetComponent<Text>().text = acts[toAct].actNumberToShow + "/" + acts[acts.Count - 1].actNumberToShow;
|
||
|
||
if (toAct == nextAct-1)
|
||
return;
|
||
|
||
//двигаем камеру к последней установленной позиции
|
||
int lastCamAct = -1;
|
||
for(int i = toAct; i >= 0;i--)
|
||
if(acts[i].type == "setCurCameraPos") { lastCamAct = i; break; };
|
||
if (lastCamAct != -1)
|
||
{
|
||
playCamera = acts[lastCamAct].setCurCameraPos.camera;
|
||
if (playCamera == "cabin")
|
||
{
|
||
curCamera = man.cabinCamera;
|
||
if (man.fusel.activeInHierarchy)
|
||
man.switchModeFree();
|
||
curCamera.transform.position = acts[lastCamAct].setCurCameraPos.position.toVector3();
|
||
curCamera.transform.rotation = acts[lastCamAct].setCurCameraPos.rotation.toQuaternion();
|
||
curCamera.GetComponent<Camera>().fieldOfView = acts[lastCamAct].setCurCameraPos.fov;
|
||
if(curCamera.transform.position.z > 6.15f)
|
||
{ // кабина
|
||
man.viewmode = 1;
|
||
curCamera.GetComponent<Camera>().farClipPlane = 100f;
|
||
curCamera.GetComponent<Camera>().fieldOfView = 50f;
|
||
man.ChangeLayerExternalPanelsIgnore();
|
||
man.ChangeLayerPilotCabineDefault();
|
||
man.ChangeLayerPassCabineIgnore();
|
||
}
|
||
else
|
||
{ // грузовая
|
||
man.viewmode = 2;
|
||
curCamera.GetComponent<Camera>().farClipPlane = 200f;
|
||
curCamera.GetComponent<Camera>().fieldOfView = 50f;
|
||
man.ChangeLayerExternalPanelsIgnore();
|
||
man.ChangeLayerPassCabineDefault();
|
||
man.ChangeLayerPilotCabineIgnore();
|
||
}
|
||
}
|
||
else
|
||
{ // внешка
|
||
man.viewmode = 3;
|
||
curCamera = man.viewCamera;
|
||
if (!man.fusel.activeInHierarchy)
|
||
man.switchModeView();
|
||
curCamera.transform.position = acts[lastCamAct].setCurCameraPos.position.toVector3();
|
||
curCamera.transform.rotation = acts[lastCamAct].setCurCameraPos.rotation.toQuaternion();
|
||
curCamera.GetComponent<CameraFree>().offset = acts[lastCamAct].setCurCameraPos.scriptOffset.toVector3();
|
||
}
|
||
}
|
||
|
||
man.isProgressBarChangingInProgress = true;
|
||
rectsList.Clear(); isRectsShowing = false;
|
||
if (!man.is3D) man.SwitchTo3D();
|
||
for (int i = 0; i <= toAct; i++)
|
||
RunAction(acts[i], true);
|
||
|
||
nextAct = toAct + 1;
|
||
|
||
man.isProgressBarChangingInProgress = false;
|
||
}
|
||
|
||
|
||
void AddToHighliteList(string objName, float sec=0f)
|
||
{
|
||
UnityObject obj = man.objects.Find(objName);
|
||
if (obj == null) return;
|
||
|
||
for (int i = 0; i < highlightList.Count; i++)
|
||
if (highlightList[i].obj.name == objName)
|
||
return;
|
||
|
||
highlightObj hObj = new highlightObj();
|
||
hObj.obj = obj; hObj.sec = sec;
|
||
|
||
if (obj.dim == "3D")
|
||
{
|
||
hObj.renderers = obj.gameObject.transform.GetComponentsInChildren<Renderer>(); //parent.
|
||
foreach (Renderer r in hObj.renderers)
|
||
{
|
||
|
||
MakeActive obj_ma = r.gameObject.GetComponent<MakeActive>();
|
||
if (obj_ma != null)
|
||
if (obj_ma.materialsReplaced)
|
||
obj_ma.RestoreChildrenMaterials();
|
||
}
|
||
|
||
hObj.materials.Clear(); hObj.greenMaterials.Clear();
|
||
for (int i = 0; i < hObj.renderers.Length; i++)
|
||
{
|
||
hObj.materials.Add(hObj.renderers[i].material);
|
||
Material greenMat = new Material(hObj.renderers[i].material);
|
||
greenMat.SetColor("_EmissionColor", new Color(0f / 255f, 50f / 255f, 0f / 255f));
|
||
hObj.greenMaterials.Add(greenMat);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
hObj.spriteRenderers = obj.gameObject.transform.GetComponentsInChildren<SpriteRenderer>(); //parent.
|
||
hObj.images = obj.gameObject.transform.GetComponentsInChildren<Image>();
|
||
hObj.spriteColors.Clear(); hObj.imageColors.Clear();
|
||
for (int i = 0; i < hObj.spriteRenderers.Length; i++)
|
||
hObj.spriteColors.Add(hObj.spriteRenderers[i].color);
|
||
for (int i = 0; i < hObj.images.Length; i++)
|
||
hObj.imageColors.Add(hObj.images[i].color);
|
||
}
|
||
highlightList.Add(hObj);
|
||
}
|
||
|
||
void RemoveFromHighliteList(string objName)
|
||
{
|
||
int ind = -1;
|
||
for (int i = 0; i < highlightList.Count; i++)
|
||
if (highlightList[i].obj.name == objName)
|
||
ind = i;
|
||
if (ind == -1) return;
|
||
highlightObj hObj = highlightList[ind];
|
||
if (hObj.obj.dim == "3D")
|
||
{
|
||
if (hObj.renderers != null && hObj.materials.Count != 0)
|
||
for (int i = 0; i < hObj.renderers.Length; i++)
|
||
hObj.renderers[i].material = hObj.materials[i];
|
||
}
|
||
else
|
||
{
|
||
for (int i = 0; i < hObj.spriteRenderers.Length; i++)
|
||
hObj.spriteRenderers[i].color = hObj.spriteColors[i];
|
||
for (int i = 0; i < hObj.images.Length; i++)
|
||
hObj.images[i].color = hObj.imageColors[i];
|
||
}
|
||
highlightList.RemoveAt(ind);
|
||
}
|
||
|
||
void HighliteRefresh()
|
||
{
|
||
for(int k=0;k < highlightList.Count;k++)
|
||
{
|
||
highlightObj hObj = highlightList[k];
|
||
if(hObj.sec != 0f)
|
||
{
|
||
hObj.sec -= highlightTimeDelta;
|
||
if(hObj.sec <= 0)
|
||
{
|
||
RemoveFromHighliteList(hObj.obj.name);
|
||
k--; continue;
|
||
}
|
||
}
|
||
|
||
if (hObj.obj.dim == "3D")
|
||
for (int i = 0; i < hObj.renderers.Length; i++)
|
||
hObj.renderers[i].material = hObj.greenMaterials[i];
|
||
else
|
||
{
|
||
for (int i = 0; i < hObj.spriteRenderers.Length; i++)
|
||
hObj.spriteRenderers[i].color = Color.green;
|
||
for (int i = 0; i < hObj.images.Length; i++)
|
||
hObj.images[i].color = Color.green;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
void ScenarioError(string msg)
|
||
{
|
||
playerText.transform.Find("PlayerTextTMP").gameObject.GetComponent<TMP_Text>().text = "<color=#aa0000>"+msg+"</color>";
|
||
playerText.SetActive(true);
|
||
if(!man.isProgressBarChangingInProgress)
|
||
Invoke("delayHide", 5f);
|
||
}
|
||
|
||
void delayHide() { playerText.SetActive(false); }
|
||
public void ScenarioMsg5sec(string msg)
|
||
{
|
||
playerText.transform.Find("PlayerTextTMP").gameObject.GetComponent<TMP_Text>().text = msg;
|
||
playerText.SetActive(true);
|
||
if (!man.isProgressBarChangingInProgress)
|
||
Invoke("delayHide", 5f);
|
||
}
|
||
|
||
public void SetFullscreenButtonClick()
|
||
{
|
||
GameObject btnGO = GameObject.Find("maxmin");
|
||
if (btnGO == null) return;
|
||
if(Application.platform == RuntimePlatform.WebGLPlayer)
|
||
{
|
||
isFullscreen = !isFullscreen;
|
||
Screen.fullScreen = isFullscreen;
|
||
}
|
||
btnGO.GetComponent<hintUI>().isGreen = false;
|
||
}
|
||
|
||
}
|
||
|
||
|
||
// setState, setStateInRange, openPanel, setTextField, setIntField, switchTo3D, highlightOn, highlightOff,
|
||
// highlightTime, waitForClick, waitForTime, setCurCameraPos, showText, hideText, execScenario, playAudio, showRect |