public override void OnInspectorGUI() { base.OnInspectorGUI(); thismount = target as Mount; var netObj = thismount.transform.GetComponentInParentEvenIfDisabled <NetObject>(); if (netObj == null) { Debug.LogWarning(thismount.name + " Mount is on a non-NetObject."); return; } usedIndexes.Clear(); MountsLookup mountslookup = netObj.GetComponent <MountsLookup>(); if (!mountslookup) { mountslookup = netObj.gameObject.AddComponent <MountsLookup>(); } mountslookup.CollectMounts(); //EditorGUI.BeginChangeCheck(); //EditorGUI.BeginChangeCheck(); EditorGUI.BeginDisabledGroup(thismount.componentIndex == 0); EditorGUILayout.PropertyField(serializedObject.FindProperty("mountType")); EditorGUI.EndDisabledGroup(); MountsLookup.DrawAllMountMappings(thismount, mountslookup); EditorGUILayout.Space(); MountSettings.Single.DrawGui(target, true, false, false, false); }
public override void OnStart() { base.OnStart(); var mountsLookup = GetComponent <MountsLookup>(); if (mountsLookup) { if (mountsLookup.mountIdLookup.ContainsKey(defaultMounting.id)) { DefaultMount = mountsLookup.mountIdLookup[defaultMounting.id]; } else { Debug.LogWarning("Sync Vitals has a Default Mount setting of " + MountSettings.Single.mountNames[defaultMounting.id] + " but no such mount is defined yet on GameObject: '" + name + "'. Root mount will be used as a failsafe."); /// Invalid default mounting (doesn't exist)... warn and set to Root defaultMounting.id = 0; DefaultMount = mountsLookup.mountIdLookup[0]; } } }
public static void DrawAllMountMappings(Mount thismount, MountsLookup mountsLookup) { EnsureStylesExists(); int usedmask = 0; int cnt = mountsLookup.indexedMounts.Count; EditorGUILayout.LabelField("All Mounts On NetObject", (GUIStyle)"BoldLabel"); /// Massive warning if too many mounts are on the object, and the last ones will not get serialized correctly. if (mountsLookup.indexedMounts.Count > MountSettings.mountTypeCount) { EditorGUILayout.HelpBox("NetObject has too many mounts. Mount count is limited to the count value in MountSettings.", MessageType.Error); } if (cnt > 0) { EditorGUILayout.BeginVertical((GUIStyle)"HelpBox"); for (int i = 0; i < mountsLookup.indexedMounts.Count; ++i) { SerializedObject mount = new SerializedObject(mountsLookup.indexedMounts[i]); var mountType = mount.FindProperty("mountType"); var index = mountType.FindPropertyRelative("id"); /// Make sure Root is selected for the first mount, and only the first mount if (i == 0) { if (index.intValue != 0) { index.intValue = 0; mount.ApplyModifiedProperties(); } } /// Switch off Root for all other mounts else if (index.intValue == 0) { index.intValue = i; mount.ApplyModifiedProperties(); Debug.LogWarning("Only the first root Mount on a NetOjbect can be set to mountType 'Root'"); } int idx = index.intValue; /// Watch for repeats int idxmask = 1 << idx; bool isAlreadyUsed = (idxmask & usedmask) != 0; usedmask |= idxmask; bool isthis = (ReferenceEquals(mount.targetObject, thismount)); const int CNT_WIDTH = 30; const int LABL_PAD = 2; /// Start drawing the row EditorGUILayout.BeginHorizontal(isthis ? mountHiliteStyle : mountNoliteStyle); /// Get the indented rect Rect indexrect = EditorGUILayout.GetControlRect(GUILayout.MaxWidth(CNT_WIDTH), GUILayout.MinWidth(CNT_WIDTH)); indexrect.xMin += 8; /// Warning Icon if (isAlreadyUsed) { EditorGUI.LabelField(new Rect(indexrect) { xMin = indexrect.xMin - 3 }, new GUIContent(EditorGUIUtility.FindTexture("CollabError"), "More than one Mount has the same compatible mount selection. Only the first will be used.")); } else { /// Index EditorGUI.BeginDisabledGroup(!isthis); EditorGUI.LabelField(indexrect, i.ToString(), mountlabelstyle); EditorGUI.EndDisabledGroup(); } /// Mount Selector float selectorWidth = EditorGUIUtility.labelWidth - (CNT_WIDTH + LABL_PAD + 8); EditorGUI.BeginDisabledGroup(i == 0); EditorGUILayout.PropertyField(mountType, GUIContent.none, GUILayout.MaxWidth(selectorWidth), GUILayout.MinWidth(selectorWidth)); EditorGUI.EndDisabledGroup(); if (isthis) { /// Object Rect thisrect = EditorGUILayout.GetControlRect(GUILayout.MinWidth(40)); thisrect.xMin += 16; EditorGUI.LabelField(thisrect, "This", mountlabelstyle); } else { EditorGUI.BeginDisabledGroup(!isthis); EditorGUILayout.ObjectField(mountsLookup.indexedMounts[i], typeof(Mount), false /*, GUILayout.MaxWidth(EditorGUIUtility.labelWidth - cntwidth), GUILayout.MinWidth(EditorGUIUtility.labelWidth - cntwidth)*/); EditorGUI.EndDisabledGroup(); } EditorGUILayout.EndHorizontal(); } EditorGUILayout.EndVertical(); } }
///// <summary> ///// Convert mountId into a mount's transform, and attach attachment. ///// </summary> ///// <param name="state"></param> ///// <param name="mountId"></param> ///// <param name="attachmentTransform"></param> ///// <param name="attachedTo"></param> //public static void AttachTransform(ObjState state, int mountId, Transform attachmentTransform, List<IOnTeleport> callbacks, Mount attachedTo = null) //{ // //Debug.Log(Time.time + " " +attachmentTransform.name + " " + state + " AttachTrans to " + attachedTo); // if ((state & ObjState.Attached) != 0) // { // var trans = StateReactors.GetAttachToTransform(attachedTo, mountId); // if (trans) // { // //attachmentTransform.localPosition = new Vector3(0, 0, 0); // //attachmentTransform.localRotation = new Quaternion(0, 0, 0, 1); // for (int i = 0; i < callbacks.Count; ++i) // callbacks[i].OnTeleport(new Vector3(), new Quaternion(), null); // attachmentTransform.parent = trans; // attachmentTransform.position = new Vector3(); // attachmentTransform.rotation = new Quaternion(); // } // } // else // { // } //} public static Transform GetAttachToTransform(Object attachedTo, int mountId) { if (attachedTo == null) { return(null); } /// First see if this is the easiest case... it is a mount already. Mount mount = attachedTo as Mount; if (!ReferenceEquals(mount, null)) { return(mount.transform); } /// Otherwise try to find a MountLookup else { var mountsLookup = attachedTo as MountsLookup; /// if not a Mounts... try getting Mounts component from the supplied object if (!mountsLookup) { Debug.Log("Not Found MountLookup"); var comp = (attachedTo as Component); if (comp) { mountsLookup = comp.GetComponent <MountsLookup>(); } var gobj = (attachedTo as GameObject); if (gobj) { mountsLookup = gobj.GetComponent <MountsLookup>(); } } /// If we found a mounts lookup with a search, try again to get a mount by ID if (!ReferenceEquals(mountsLookup, null)) { Debug.Log("Found MountLookup"); bool success = mountsLookup.mountIdLookup.TryGetValue(mountId, out mount); if (success) { Debug.Log("Found Mount with ID " + mount.name); return(mount.transform); } else { return(mountsLookup.transform); } } } /// All other cases we are after the transform Transform tr = (attachedTo as Transform); if (tr) { return(tr); } GameObject go = attachedTo as GameObject; if (go) { return(go.transform); } if (tr) { return(tr); } return(null); }
public void OnStateChange(ObjState state, Transform pickup, Mount attachedTo = null, bool isReady = true) { #if UNITY_EDITOR currentState = state; #endif bool show; if (!isReady) { //Debug.Log(name + " not ready!"); show = false; } else { bool match = stateLogic.Evaluate((int)state); if (match) { show = true; /// If there is no object to attach to yet (due to keyframes) we need to keep this invisible. if (reactToAttached) { if (attachedTo == null) { show = false; } } } else { show = false; } } //Debug.Log(name + " <b>toggle!</b>" + toggle + " " + show); switch (toggle) { case DisplayToggle.GameObject: { _gameObject.SetActive(show); break; } case DisplayToggle.Component: { if (monob) { monob.enabled = show; } break; } case DisplayToggle.Renderer: { if (_renderer) { _renderer.enabled = show; } break; } } }
/// <summary> /// Modify StateChange call if the mount was invalid (Mount likely destroyed). /// </summary> protected virtual void InvalidMountHandler(ObjState newState, Mount newMount, bool force) { ChangeState(new StateChangeInfo(ObjState.Visible, null, true)); }
/// <summary> /// Call this method to change the state of this object. This state will be synced over the network, /// and callbacks will trigger locally and remotely. Typically it is preferred to call QueueStateChange(), /// which will defer the ChangeState application until the appropriate timing. /// </summary> protected virtual void ChangeState(StateChangeInfo stateChangeInfo) { if (!gameObject) { Debug.LogWarning(name + " has been destroyed. Will not try to change state."); return; } //if (IsMine) // //if (GetComponent<SyncVitals>()) // { // if (stateChangeInfo.objState == ObjState.Visible) // Debug.Log(Time.time + " " + stateChangeInfo); // else // Debug.Log(Time.time + " <b>" + stateChangeInfo + "</b>"); // } var oldState = currentState.state; var oldMount = currentMount; var newState = stateChangeInfo.objState; var newMount = stateChangeInfo.mount; bool respawn; /// Assuming first Visible after a despawn is a Respawn - this is here to handle lost teleport packets if (autoReset && oldState == ObjState.Despawned && newState != ObjState.Despawned) { stateChangeInfo = new StateChangeInfo(respawnStateInfo) { objState = stateChangeInfo.objState }; respawn = true; } else { respawn = false; } var force = stateChangeInfo.force; bool stateChanged = newState != oldState; bool mountChanged = oldMount != newMount; var prevParent = transform.parent; /// Test nothing has changed if (!force && !stateChanged && !mountChanged) { return; } bool nowAttached = (newState & ObjState.Attached) != 0; /// Handling for attached without a valid Mount if (nowAttached && !newMount) { //Debug.LogError(name + " Attached with a null mount! " + newState); InvalidMountHandler(newState, newMount, force); return; } if (IsMine) { if (mountChanged || respawn) { ////Debug.LogError("TELEPORT"); //for (int i = 0; i < onTeleportCallbacks.Count; ++i) // onTeleportCallbacks[i].OnTeleport(); } } /// The State is attached /*else*/ if (mountChanged) { /// Attaching to a mount // If Attached bit is true if (nowAttached) { //Debug.Log(Time.time + " " + name + " ATTACH " + newMount.name + " "); currentState.attachedToNetId = newMount.NetObjId; currentState.attachedToMountTypeId = newMount.mountType.id; transform.parent = newMount.transform; bool nowMounted = (newState & ObjState.Mounted) != 0; // If Mounted bit is true if (nowMounted) { //Debug.Log(name + " Hard Mounting Origin"); transform.localPosition = new Vector3(); transform.localRotation = new Quaternion(); } } /// Detaching from a mount else { //Debug.Log(Time.time + " " + name + " DEATTACH "); currentState.attachedToNetId = null; currentState.attachedToMountTypeId = null; transform.parent = null; } Mount.ChangeMounting(this, newMount); } var pos = stateChangeInfo.offsetPos; var rot = stateChangeInfo.offsetRot; var vel = stateChangeInfo.velocity; if (rot.HasValue) { //Debug.Log(Time.time + " " + name + " STATE ROT APPLY " + rot.Value); transform.localEulerAngles = rot.Value; } if (pos.HasValue) { if (respawn) { transform.localPosition = pos.Value; } else { var parRot = prevParent ? prevParent.rotation : transform.rotation; transform.position = transform.position + parRot * pos.Value; } } if (vel.HasValue) { var rb = syncState.Rb; if (rb) { if (!rb.isKinematic) { rb.velocity = ((prevParent) ? prevParent.rotation : rb.rotation) * vel.Value; } } else { var rb2d = syncState.Rb2d; if (rb2d) { if (!rb2d.isKinematic) { rb2d.velocity = stateChangeInfo.velocity.Value; } } } } currentState.state = newState; currentMount = newMount; ///// Apply the vector values //this.ApplyVectors(stateChangeInfo, prevParent, onTeleportCallbacks); /// Send out callbacks for (int i = 0; i < onStateChangeCallbacks.Count; ++i) { onStateChangeCallbacks[i].OnStateChange(newState, transform, currentMount, netObjIsReady); } }
public void Drop(Mount newMount, bool force = false) { const ObjState state = ObjState.Visible | ObjState.Dropped; stateChangeQueue.Enqueue(new StateChangeInfo(state, newMount, force)); }