/// <summary> /// Removes a specific <see cref="Component"/> from this GameObject. /// </summary> /// <param name="cmp">The Component to remove from this GameObject</param> /// <exception cref="System.ArgumentNullException">Thrown when the specified Component is a null reference.</exception> /// <exception cref="System.ArgumentException">Thrown when the specified Component does not belong to this GameObject</exception> /// <seealso cref="RemoveComponent(Type)"/> /// <seealso cref="RemoveComponent{T}()"/> public void RemoveComponent(Component cmp) { if (cmp == null) { throw new ArgumentNullException("cmp", "Can't remove a null reference Component"); } if (cmp.gameobj != this) { throw new ArgumentException("The specified Component does not belong to this GameObject", "cmp"); } this.OnComponentRemoving(cmp); this.compMap.Remove(cmp.GetType()); this.compList.Remove(cmp); if (cmp is Components.Transform) { this.compTransform = null; } cmp.gameobj = null; SetComponentExecutionOrder(); }
public void Update(Transform referenceObj) { if (this.method == InputMethod.Unknown) { if (Time.FrameCount - this.creationFrame < 5) return; InputMethod[] takenMethods = Scene.Current.FindComponents<Player>() .Select(p => p.InputMethod) .Where(m => m != InputMethod.Unknown) .ToArray(); InputMethod[] freeMethods = Enum.GetValues(typeof(InputMethod)) .Cast<InputMethod>() .Except(takenMethods) .ToArray(); for (int i = 0; i < freeMethods.Length; i++) { if (this.Detect(freeMethods[i])) { this.method = freeMethods[i]; break; } } } else { this.UpdateFrom(referenceObj, this.method); } }
/// <summary> /// Adds the specified <see cref="Component"/> to this GameObject, if no Component of that Type is already part of this GameObject. /// Simply uses the already added Component otherwise. /// </summary> /// <typeparam name="T">The Components Type.</typeparam> /// <param name="newComp">The Component instance to add to this GameObject.</param> /// <returns>A reference to a Component of the specified Type</returns> /// <exception cref="System.ArgumentException">Thrown if the specified Component is already attached to a GameObject</exception> public T AddComponent <T>(T newComp) where T : Component { if (newComp.gameobj != null) { throw new ArgumentException(String.Format( "Specified Component '{0}' is already part of another GameObject '{1}'", Log.Type(newComp.GetType()), newComp.gameobj.FullName)); } Type cType = newComp.GetType(); if (this.compMap.ContainsKey(cType)) { return(this.compMap[cType] as T); } newComp.gameobj = this; this.compMap.Add(cType, newComp); this.compList.Add(newComp); if (newComp is Components.Transform) { this.compTransform = (Components.Transform)(Component) newComp; } this.OnComponentAdded(newComp); return(newComp); }
/// <summary> /// Removes all <see cref="Component">Components</see> from this GameObject. /// </summary> public void ClearComponents() { foreach (Component c in this.compList) { this.OnComponentRemoving(c); c.gameobj = null; } this.compList.Clear(); this.compMap.Clear(); this.compTransform = null; }
private void DisposeTransform() { if (_transform == null) return; if (_transform.GameObj != null && _transform.GameObj.Parent != null) _transform.GameObj.Parent.Dispose(); else if (_transform.GameObj != null) _transform.GameObj.Dispose(); _transform = null; }
public void OnInit(InitContext context) { if (context == InitContext.Activate) { _defaultOffset = Offset; if (TrackedObject == null) return; _trackedObjectTransform = TrackedObject.GetComponent<Transform>(); if (_trackedObjectTransform == null) { Log.Game.WriteError("{0} is tracking {1} which doesn't have a transform component.", GameObj, TrackedObject); } } }
private void CreateTransform(bool createWithParent) { var gameObject = new GameObject("Object"); _transform = gameObject.AddComponent<Transform>(); _transform.Pos = _expectedPosition; if (createWithParent) { _parentPosition = new Vector3(3, 3, 3); var parent = new GameObject("Parent"); var parentTransform = parent.AddComponent<Transform>(); parentTransform.Pos = _parentPosition; gameObject.Parent = parent; } }
private void UpdateFromMouseAndKeyboard(Transform referenceObj, MouseInput mouse, KeyboardInput keyboard) { Camera mainCamera = Scene.Current.FindComponent<Camera>(); Vector3 objPos = (referenceObj != null) ? referenceObj.Pos : Vector3.Zero; Vector2 objPosOnScreen = (mainCamera != null) ? mainCamera.GetScreenCoord(objPos).Xy : Vector2.Zero; this.controlLookAngle = (mouse.Pos - objPosOnScreen).Angle; this.controlLookSpeed = MathF.Clamp((mouse.Pos - objPosOnScreen).Length / 100.0f, 0.0f, 1.0f); this.controlMovement = Vector2.Zero; { if (keyboard[Key.W]) this.controlMovement += new Vector2(0.0f, -1.0f); if (keyboard[Key.A]) this.controlMovement += new Vector2(-1.0f, 0.0f); if (keyboard[Key.S]) this.controlMovement += new Vector2(0.0f, 1.0f); if (keyboard[Key.D]) this.controlMovement += new Vector2(1.0f, 0.0f); } if (this.controlMovement.Length > 1.0f) this.controlMovement.Normalize(); this.controlFireWeapon = mouse[MouseButton.Left]; this.controlQuit = keyboard.KeyHit(Key.Escape); this.controlStart = keyboard.KeyHit(Key.Enter); }
private void FireBullet(RigidBody body, Transform transform, Vector2 localPos, float localAngle) { ShipBlueprint blueprint = this.blueprint.Res; if (blueprint.BulletType == null) return; Bullet bullet = blueprint.BulletType.Res.CreateBullet(); Vector2 recoilImpulse; Vector2 worldPos = transform.GetWorldPoint(localPos); bullet.Fire(this.owner, body.LinearVelocity, worldPos, transform.Angle + localAngle, out recoilImpulse); body.ApplyWorldImpulse(recoilImpulse); Scene.Current.AddObject(bullet.GameObj); SoundInstance inst = null; if (Player.AlivePlayers.Count() > 1) inst = DualityApp.Sound.PlaySound3D(this.owner.WeaponSound, new Vector3(worldPos)); else inst = DualityApp.Sound.PlaySound(this.owner.WeaponSound); inst.Volume = MathF.Rnd.NextFloat(0.6f, 1.0f); inst.Pitch = MathF.Rnd.NextFloat(0.9f, 1.11f); }
public TransformChangedEventArgs(Component transform, Transform.DirtyFlags dirtyFlags) : base(transform) { this.dirtyFlags = dirtyFlags; }
private void Parent_EventComponentRemoving(object sender, ComponentEventArgs e) { if (this.parentTransform != null) { Transform cmpTransform = e.Component as Transform; if (cmpTransform == this.parentTransform) { cmpTransform.GameObj.EventComponentAdded += this.Parent_EventComponentAdded; cmpTransform.GameObj.EventComponentRemoving -= this.Parent_EventComponentRemoving; this.parentTransform = null; this.UpdateRel(); } } }
private void UpdateFromGamepad(Transform referenceObj, GamepadInput gamepad) { float referenceAngle = (referenceObj != null) ? referenceObj.Angle : 0.0f; if (gamepad.LeftThumbstick.Length > 0.25f) { float mappedLength = (gamepad.LeftThumbstick.Length - 0.25f) / 0.75f; this.controlMovement = gamepad.LeftThumbstick * mappedLength / gamepad.LeftThumbstick.Length; } else { this.controlMovement = Vector2.Zero; } if (gamepad.RightThumbstick.Length > 0.5f) { this.controlLookAngle = gamepad.RightThumbstick.Angle; this.controlLookSpeed = (gamepad.RightThumbstick.Length - 0.5f) / 0.5f; } else if (gamepad.LeftThumbstick.Length > 0.25f) { this.controlLookAngle = gamepad.LeftThumbstick.Angle; this.controlLookSpeed = (gamepad.LeftThumbstick.Length - 0.25f) / 0.75f; } bool targetAimed = MathF.CircularDist(referenceAngle, this.controlLookAngle) < MathF.RadAngle1 * 10; this.controlFireWeapon = (targetAimed && gamepad.RightThumbstick.Length > 0.9f) || gamepad[GamepadAxis.RightTrigger] > 0.5f || gamepad[GamepadButton.RightShoulder] || gamepad[GamepadButton.A]; this.controlQuit = gamepad.ButtonHit(GamepadButton.Back); this.controlStart = gamepad.ButtonHit(GamepadButton.Start); }
/// <summary> /// Updates the Transforms data all at once. /// </summary> /// <param name="other"></param> public void SetTransform(Transform other) { if (other == this) return; this.SetTransform(other.Pos, other.Scale, other.Angle); }
private void DrawVertexHandles(Canvas canvas, Vector2[] polyVert, float colliderAlpha,Transform bodyTransform) { foreach (Vector2 vertex in polyVert) { bool vertexSelected = IsSelected(v => (v.ActualObject as Vector2?) == vertex); float vertexAlpha = colliderAlpha*(vertexSelected ? 1.0f : 0.5f); ColorRgba color = this.VertexColor.WithAlpha(vertexAlpha); canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, color)); float z = bodyTransform.Pos.Z; float size = VertexSize/GetScaleAtZ(z); Vector2 position = bodyTransform.GetWorldPoint(vertex); canvas.FillRect(position.X - size/2, position.Y - size/2, z, size, size); canvas.DrawRect(position.X - size/2, position.Y - size/2, z, size, size); } }
private bool IsOutlineBoxIntersection(Transform transform, Vector2[] vertices, Rect box) { bool hit = false; for (int i = 0; i < vertices.Length; i++) { Vector2 worldV1 = transform.GetWorldPoint(vertices[i]); Vector2 worldV2 = transform.GetWorldPoint(vertices[(i + 1) % vertices.Length]); hit = hit || MathF.LinesCross( box.TopLeft.X, box.TopLeft.Y, box.TopRight.X, box.TopRight.Y, worldV1.X, worldV1.Y, worldV2.X, worldV2.Y); hit = hit || MathF.LinesCross( box.TopLeft.X, box.TopLeft.Y, box.BottomLeft.X, box.BottomLeft.Y, worldV1.X, worldV1.Y, worldV2.X, worldV2.Y); hit = hit || MathF.LinesCross( box.BottomRight.X, box.BottomRight.Y, box.TopRight.X, box.TopRight.Y, worldV1.X, worldV1.Y, worldV2.X, worldV2.Y); hit = hit || MathF.LinesCross( box.BottomRight.X, box.BottomRight.Y, box.BottomLeft.X, box.BottomLeft.Y, worldV1.X, worldV1.Y, worldV2.X, worldV2.Y); hit = hit || box.Contains(worldV1) || box.Contains(worldV2); if (hit) return true; } return false; }
/// <summary> /// Updates the Transforms data all at once. /// </summary> /// <param name="other"></param> public void SetRelativeTransform(Transform other) { if (other == this) return; this.SetRelativeTransform(other.RelativePos, other.RelativeScale, other.RelativeAngle); }
void ICmpInitializable.OnInit(InitContext context) { if (context == InitContext.AddToGameObject || context == InitContext.Loaded) { this.gameobj.EventParentChanged += this.gameobj_EventParentChanged; if (this.gameobj.Parent != null) { this.parentTransform = this.gameobj.Parent.Transform; if (this.parentTransform == null) this.gameobj.Parent.EventComponentAdded += this.Parent_EventComponentAdded; else this.gameobj.Parent.EventComponentRemoving += this.Parent_EventComponentRemoving; } else this.parentTransform = null; this.UpdateRel(); } }
void ICmpGameObjectListener.OnGameObjectParentChanged(GameObject oldParent, GameObject newParent) { if (oldParent != null) { if (this.parentTransform == null) oldParent.EventComponentAdded -= this.Parent_EventComponentAdded; else oldParent.EventComponentRemoving -= this.Parent_EventComponentRemoving; } if (newParent != null) { this.parentTransform = newParent.Transform; if (this.parentTransform == null) newParent.EventComponentAdded += this.Parent_EventComponentAdded; else newParent.EventComponentRemoving += this.Parent_EventComponentRemoving; } else this.parentTransform = null; this.UpdateRel(); }
/// <summary> /// Updates the SoundInstance /// </summary> public void Update() { if (!DualityApp.Sound.IsAvailable) { return; } lock (this.strLock) { // Check existence of attachTo object if (this.attachedTo != null && this.attachedTo.Disposed) { this.attachedTo = null; } // Retrieve sound resource values Sound soundRes = this.sound.Res; AudioData audioDataRes = this.audioData.Res; if (soundRes == null || audioDataRes == null) { this.Dispose(); return; } float optVolFactor = this.GetTypeVolFactor(); float minDistTemp = soundRes.MinDist; float maxDistTemp = soundRes.MaxDist; float volTemp = optVolFactor * soundRes.VolumeFactor * this.vol * this.curFade * this.pauseFade; float pitchTemp = soundRes.PitchFactor * this.pitch; float priorityTemp = 1000.0f; priorityTemp *= volTemp; // Calculate 3D source values, distance and priority Vector3 posAbs = this.pos; Vector3 velAbs = this.vel; if (this.is3D) { Components.Transform attachTransform = this.attachedTo != null ? this.attachedTo.Transform : null; // Attach to object if (this.attachedTo != null && this.attachedTo != DualityApp.Sound.Listener) { MathF.TransformCoord(ref posAbs.X, ref posAbs.Y, attachTransform.Angle); MathF.TransformCoord(ref velAbs.X, ref velAbs.Y, attachTransform.Angle); posAbs += attachTransform.Pos; velAbs += attachTransform.Vel; } // Distance check Vector3 listenerPos = DualityApp.Sound.ListenerPos; float dist; if (this.attachedTo != DualityApp.Sound.Listener) { dist = MathF.Sqrt( (posAbs.X - listenerPos.X) * (posAbs.X - listenerPos.X) + (posAbs.Y - listenerPos.Y) * (posAbs.Y - listenerPos.Y) + (posAbs.Z - listenerPos.Z) * (posAbs.Z - listenerPos.Z) * 0.25f); } else { dist = MathF.Sqrt( posAbs.X * posAbs.X + posAbs.Y * posAbs.Y + posAbs.Z * posAbs.Z * 0.25f); } if (dist > maxDistTemp) { this.Dispose(); return; } else { priorityTemp *= Math.Max(0.0f, 1.0f - (dist - minDistTemp) / (maxDistTemp - minDistTemp)); } } // Grab an OpenAL source, if not yet assigned if (this.alSource == AlSource_NotYetAssigned) { if (this.GrabAlSource()) { this.RegisterPlaying(); } else { this.Dispose(); return; } } // Determine source state, if available ALSourceState stateTemp = ALSourceState.Stopped; bool sourceAvailable = this.alSource > AlSource_NotAvailable; if (sourceAvailable) { stateTemp = AL.GetSourceState(this.alSource); } // If the source is stopped / finished, dispose and return if (stateTemp == ALSourceState.Stopped && (!audioDataRes.IsStreamed || this.strStopReq != StopRequest.None)) { this.Dispose(); return; } else if (stateTemp == ALSourceState.Initial && this.strStopReq == StopRequest.Immediately) { this.Dispose(); return; } // Fading in and out bool fadeOut = this.fadeTarget <= 0.0f; if (!this.paused) { if (this.fadeTarget != this.curFade) { float fadeTemp = Time.TimeMult * Time.SPFMult / Math.Max(0.05f, this.fadeTimeSec); if (this.fadeTarget > this.curFade) { this.curFade += fadeTemp; } else { this.curFade -= fadeTemp; } if (Math.Abs(this.curFade - this.fadeTarget) < fadeTemp * 2.0f) { this.curFade = this.fadeTarget; } this.dirtyState |= DirtyFlag.Vol; } } // Special paused-fading if (this.paused && this.pauseFade > 0.0f) { this.pauseFade = MathF.Max(0.0f, this.pauseFade - Time.TimeMult * Time.SPFMult * 5.0f); this.dirtyState |= DirtyFlag.Paused | DirtyFlag.Vol; } else if (!this.paused && this.pauseFade < 1.0f) { this.pauseFade = MathF.Min(1.0f, this.pauseFade + Time.TimeMult * Time.SPFMult * 5.0f); this.dirtyState |= DirtyFlag.Paused | DirtyFlag.Vol; } // SlowMotion //if (this.type == SoundType.EffectWorld) //{ // pitchTemp *= (float)Math.Max(0.5d, SteApp.Current.SlowMotion); // volTemp *= 2.0f * (float)Math.Min(0.5d, SteApp.Current.SlowMotion); // // Hack: Pitch always dirty // this.dirtyState |= DirtyFlag.Pitch; //} //else if (this.type == SoundType.Speech) //{ // volTemp *= (float)Math.Sqrt(SteApp.Current.SlowMotion); //} // Hack: Volume always dirty - just to be sure this.dirtyState |= DirtyFlag.Vol; if (sourceAvailable) { if (this.is3D) { // Hack: Relative always dirty to support switching listeners without establishing a notifier-event this.dirtyState |= DirtyFlag.Relative; if (this.attachedTo != null) { this.dirtyState |= DirtyFlag.AttachedTo; } if ((this.dirtyState & DirtyFlag.Relative) != DirtyFlag.None) { AL.Source(this.alSource, ALSourceb.SourceRelative, this.attachedTo == DualityApp.Sound.Listener); } if ((this.dirtyState & DirtyFlag.Pos) != DirtyFlag.None) { AL.Source(this.alSource, ALSource3f.Position, posAbs.X, -posAbs.Y, -posAbs.Z * 0.5f); } if ((this.dirtyState & DirtyFlag.Vel) != DirtyFlag.None) { AL.Source(this.alSource, ALSource3f.Velocity, velAbs.X, -velAbs.Y, -velAbs.Z); } } else { if ((this.dirtyState & DirtyFlag.Relative) != DirtyFlag.None) { AL.Source(this.alSource, ALSourceb.SourceRelative, true); } if ((this.dirtyState & DirtyFlag.Pos) != DirtyFlag.None) { AL.Source(this.alSource, ALSource3f.Position, 0.0f, 0.0f, 0.0f); } if ((this.dirtyState & DirtyFlag.Vel) != DirtyFlag.None) { AL.Source(this.alSource, ALSource3f.Velocity, 0.0f, 0.0f, 0.0f); } } if ((this.dirtyState & DirtyFlag.MaxDist) != DirtyFlag.None) { AL.Source(this.alSource, ALSourcef.MaxDistance, maxDistTemp); } if ((this.dirtyState & DirtyFlag.RefDist) != DirtyFlag.None) { AL.Source(this.alSource, ALSourcef.ReferenceDistance, minDistTemp); } if ((this.dirtyState & DirtyFlag.Loop) != DirtyFlag.None) { AL.Source(this.alSource, ALSourceb.Looping, (this.looped && !audioDataRes.IsStreamed)); } if ((this.dirtyState & DirtyFlag.Vol) != DirtyFlag.None) { AL.Source(this.alSource, ALSourcef.Gain, volTemp); } if ((this.dirtyState & DirtyFlag.Pitch) != DirtyFlag.None) { AL.Source(this.alSource, ALSourcef.Pitch, pitchTemp); } if ((this.dirtyState & DirtyFlag.Paused) != DirtyFlag.None) { if (this.paused && this.pauseFade == 0.0f && stateTemp == ALSourceState.Playing) { AL.SourcePause(this.alSource); } else if ((!this.paused || this.pauseFade > 0.0f) && stateTemp == ALSourceState.Paused) { AL.SourcePlay(this.alSource); } } } this.dirtyState = DirtyFlag.None; // Update play time if (!this.paused) { this.playTime += MathF.Max(0.5f, pitchTemp) * Time.TimeMult * Time.SPFMult; if (this.sound.Res.FadeOutAt > 0.0f && this.playTime >= this.sound.Res.FadeOutAt) { this.FadeOut(this.sound.Res.FadeOutTime); } } // Finish priority calculation this.curPriority = (int)Math.Round(priorityTemp / Math.Sqrt(DualityApp.Sound.GetNumPlaying(this.sound))); // Initially play the source if (stateTemp == ALSourceState.Initial && !this.paused) { if (audioDataRes.IsStreamed) { this.isStreamed = true; DualityApp.Sound.EnqueueForStreaming(this); } else { AL.SourceQueueBuffer(this.alSource, audioDataRes.AlBuffer); AL.SourcePlay(this.alSource); } } // Remove faded out sources if (fadeOut && volTemp <= 0.0f) { this.fadeWaitEnd += Time.TimeMult * Time.MsPFMult; // After fading out entirely, wait 50 ms before actually stopping the source to prevent unpleasant audio tick / glitch noises if (this.fadeWaitEnd > 50.0f) { this.Dispose(); return; } } else { this.fadeWaitEnd = 0.0f; } } }
private void UpdateFrom(Transform referenceObj, InputMethod method) { switch (method) { case InputMethod.MouseAndKeyboard: this.UpdateFromMouseAndKeyboard(referenceObj, DualityApp.Mouse, DualityApp.Keyboard); break; case InputMethod.FirstGamepad: this.UpdateFromGamepad(referenceObj, DualityApp.Gamepads[0]); break; case InputMethod.SecondGamepad: this.UpdateFromGamepad(referenceObj, DualityApp.Gamepads[1]); break; } }
private void gameobj_EventParentChanged(object sender, GameObjectParentChangedEventArgs e) { if (e.OldParent != null) { if (this.parentTransform == null) e.OldParent.EventComponentAdded -= this.Parent_EventComponentAdded; else e.OldParent.EventComponentRemoving -= this.Parent_EventComponentRemoving; } if (e.NewParent != null) { this.parentTransform = e.NewParent.Transform; if (this.parentTransform == null) e.NewParent.EventComponentAdded += this.Parent_EventComponentAdded; else e.NewParent.EventComponentRemoving += this.Parent_EventComponentRemoving; } else this.parentTransform = null; this.UpdateRel(); }
void ICmpInitializable.OnShutdown(ShutdownContext context) { if (context == ShutdownContext.RemovingFromGameObject) { this.gameobj.EventParentChanged -= this.gameobj_EventParentChanged; if (this.gameobj.Parent != null) { if (this.parentTransform == null) this.gameobj.Parent.EventComponentAdded -= this.Parent_EventComponentAdded; else this.gameobj.Parent.EventComponentRemoving -= this.Parent_EventComponentRemoving; } this.parentTransform = null; this.UpdateRel(); } }
public void OnInit(InitContext context) { transform = (Transform)GameObj.GetComponent(typeof(Transform)); }