public void FireBullet(APCharacterController launcher, AttackContext context) { if (CanFireBullet()) { if (!m_infiniteAmmo) { m_ammoBox.AddAmmo(-1); } // make sure move horizontal direction is valid bool bFaceRight = launcher.GetMotor().m_faceRight; float fAngle = Mathf.Deg2Rad * context.m_bulletDirection; Vector2 v2MoveDir = new Vector2(Mathf.Cos(fAngle), -Mathf.Sin(fAngle)); if (bFaceRight && v2MoveDir.x < 0f || !bFaceRight && v2MoveDir.x > 0f) { v2MoveDir.x = -v2MoveDir.x; } // spawn and launch bullet (add player velocity before spawn) Vector2 pointPos = launcher.transform.TransformPoint(context.m_bulletStartPosition); pointPos = pointPos + (Time.deltaTime * launcher.GetMotor().m_velocity); float bulletSign = m_bullet.m_faceRight ? 1f : -1f; Quaternion rot = Quaternion.Euler(0f, 0f, bFaceRight != m_bullet.m_faceRight ? bulletSign * context.m_bulletDirection : -bulletSign * context.m_bulletDirection); APBullet newBullet = (APBullet)UnityEngine.Object.Instantiate(m_bullet, pointPos, rot); newBullet.enabled = true; // init bullet v2MoveDir = launcher.transform.TransformDirection(v2MoveDir); newBullet.Setup(launcher, v2MoveDir); // launch listeners launcher.EventListeners.ForEach(e => e.OnAttackBulletFired(this, newBullet)); } }
// Update is called once per frame void Update() { // handle god mode here if (m_godMode && Time.time > m_godModeTime + m_godModeTimeWhenHit) { if (m_anim) { m_anim.SetBool("GodMode", false); } m_godMode = false; // restore previous layer mask m_player.GetMotor().m_rayLayer = m_prevCollisionLayer; } }
public void Setup(APCharacterController launcher, Vector2 startPos, Vector2 moveDir) { m_anim = GetComponent <Animator>(); m_launcher = launcher; m_alive = true; m_spawnDuration = 0f; m_curVel = moveDir * m_velocity; m_rigidBody = GetComponent <Rigidbody2D>(); if (m_rigidBody) { m_rigidBody.velocity = m_curVel; } // fix flipping if (launcher.GetMotor().FaceRight != m_faceRight) { Vector3 theScale = transform.localScale; theScale.x *= -1; theScale.y *= -1; transform.localScale = theScale; Quaternion localRot = transform.localRotation; Vector3 rot = localRot.eulerAngles; rot.z *= -1; localRot.eulerAngles = rot; transform.localRotation = localRot; } }
// called when character is touching us with a ray override public bool OnCharacterTouch(APCharacterController launcher, APCharacterMotor.RayType rayType, RaycastHit2D hit, float penetration, APMaterial hitMaterial) { // ignore contacts for exploded crates if (IsDead()) { return(false); } // check if we are touching with vertical down shift attack if (!m_shiftHit && launcher.IsShifting() && launcher.GetMotor().m_velocity.y < 0f) { // handle different penetration in function of ray type if ((rayType == APCharacterMotor.RayType.Ground && penetration < 0.1f) || (rayType != APCharacterMotor.RayType.Ground && penetration < 0f)) { // defer hit (as this callback may be called for many rays) m_shiftHit = true; } } // ignore all contacts after a shift hit if (m_shiftHit) { return(false); } // always allow contact with crate return(true); }
void ReleaseControl(ExitType EExitType) { if (m_controlled) { m_bPhysicAnim = false; // keep release time if (EExitType != ExitType.ClimbExit) { m_releaseTime = Time.time; } // Leave control m_controlled.EventListeners.ForEach(e => e.OnEdgeGrabEnd(this)); m_controlled.IsControlled = false; // exit with small impulse if (EExitType == ExitType.Jump) { APCharacterMotor motor = m_controlled.GetMotor(); motor.m_velocity = m_jumpExitPower; float horAxis = m_controlled.m_inputs.m_axisX.GetValue(); motor.m_velocity.x *= horAxis; // make sure to exit in right side if ((motor.m_velocity.x > 0f && !motor.FaceRight) || (motor.m_velocity.x < 0f && motor.FaceRight)) { motor.Flip(); } } else if (EExitType == ExitType.ClimbExit) { float fClampedInput = GetClampedInput(); // inject exit character velocity float fGroundSpeed = m_controlled.ComputeMaxGroundSpeed(); m_controlled.GetMotor().m_velocity = Vector2.right * fClampedInput * fGroundSpeed; // limit exit input m_controlled.m_inputs.m_axisX.ResetValue(fClampedInput); } m_controlled = null; } }
public void FireBullet(APCharacterController launcher, ContextId contextId) { if ((m_ammo > 0 || m_infiniteAmmo) && (m_bullet != null)) { if (!m_infiniteAmmo) { m_ammo--; } AttackContext curContext = m_contextStand; switch (contextId) { case ContextId.eRun: curContext = m_contextRun; break; case ContextId.eInAir: curContext = m_contextInAir; break; case ContextId.eCrouched: curContext = m_contextCrouched; break; } // make sure move horizontal direction is valid float fAngle = Mathf.Deg2Rad * curContext.m_bulletDirection; Vector2 v2MoveDir = new Vector2(Mathf.Cos(fAngle), -Mathf.Sin(fAngle)); if (launcher.GetMotor().m_faceRight&& v2MoveDir.x < 0f || !launcher.GetMotor().m_faceRight&& v2MoveDir.x > 0f) { v2MoveDir.x = -v2MoveDir.x; } // spawn and launch bullet (add player velocity before spawn) Vector2 pointPos = launcher.transform.TransformPoint(curContext.m_bulletStartPosition); pointPos = pointPos + (Time.deltaTime * launcher.GetMotor().m_velocity); APBullet newBullet = (APBullet)UnityEngine.Object.Instantiate(m_bullet, pointPos, Quaternion.identity); // init bullet v2MoveDir = launcher.transform.TransformDirection(v2MoveDir); newBullet.Setup(launcher, pointPos, v2MoveDir); // launch listeners launcher.EventListeners.ForEach(e => e.OnAttackBulletFired(this, newBullet)); } }
void StartGrab(APCharacterController controlled, APAnimation anim, Vector2 grabHandle) { ClearRuntimeValues(); m_controlled = controlled; m_controlled.IsControlled = true; // Init handle to grab m_curGrabHandle = transform.TransformPoint(grabHandle); MatchGrabAnchor(); // start anim & reset velocity m_controlled.GetMotor().m_velocity = Vector2.zero; InitPhysAnimation(m_curGrabHandle); m_controlled.PlayAnim(anim); // launch events m_controlled.EventListeners.ForEach(e => e.OnEdgeGrabStart(this)); }
public bool TryTakeControl(APCharacterController controlled, Collider2D otherCollider) { if (enabled && !m_controlled) { // check grabbing mode if (otherCollider == m_colliderFromTop && m_grabFromTop.m_enabled && m_grabFromTop.m_button.IsSpecified()) { // make sure correct input is pushed while in trigger if (m_grabFromTop.m_button.GetButton()) { // flip player if not facing correctly if (controlled.IsFacingRight() != (m_direction == Direction.Right)) { controlled.GetMotor().Flip(); } StartGrab(controlled, m_grabFromTop.m_anim, m_grabFromTop.m_handle); return(true); } } else if (otherCollider == m_colliderAligned && m_grabInAir.m_enabled) { // make sure we do not grab same edge too quickly while in air if (Time.time - m_releaseTime < controlled.m_edgeGrab.m_minTimeBetweenEdgeGrabs) { return(false); } // check direction if (m_direction == Direction.Right && controlled.IsFacingRight() || m_direction == Direction.Left && !controlled.IsFacingRight()) { StartGrab(controlled, m_grabInAir.m_anim, m_grabInAir.m_handle); return(true); } } } return(false); }
void UpdateCamera() { float camX = transform.position.x; float camY = transform.position.y; float fOffsetX = 0f; float fOffsetY = 0f; Vector2 v2Diff = player.position - transform.position; v2Diff += m_offset; // Handle face leading here if (m_character) { float fMinSpeed = 0.1f; if ((m_faceLeadMode == FaceLeadMode.Input && m_character.m_inputs.m_axisX.GetValue() > 0f) || (m_faceLeadMode == FaceLeadMode.CharacterSpeed && m_character.GetMotor().m_velocity.x > fMinSpeed)) { m_dynOffset += Time.deltaTime * m_faceLeadPower; m_dynOffset = Mathf.Min(m_faceLead, m_dynOffset); } else if (!m_NoBackward && ((m_faceLeadMode == FaceLeadMode.Input && m_character.m_inputs.m_axisX.GetValue() < 0f) || (m_faceLeadMode == FaceLeadMode.CharacterSpeed && m_character.GetMotor().m_velocity.x < -fMinSpeed))) { m_dynOffset -= Time.deltaTime * m_faceLeadPower; m_dynOffset = Mathf.Max(-m_faceLead, m_dynOffset); } v2Diff.x += m_dynOffset; } /* * Vector3 camPosOffset = transform.position - new Vector3(m_offset.x + m_dynOffset, m_offset.y, 0f); * Debug.DrawLine(camPosOffset + new Vector3(-m_marginX, -m_marginY, 0f), * camPosOffset + new Vector3(-m_marginX, m_marginY, 0f)); * * Debug.DrawLine(camPosOffset + new Vector3(-m_marginX, m_marginY, 0f), * camPosOffset + new Vector3(m_marginX, m_marginY, 0f)); * * Debug.DrawLine(camPosOffset + new Vector3(m_marginX, m_marginY, 0f), * camPosOffset + new Vector3(m_marginX, -m_marginY, 0f)); * * Debug.DrawLine(camPosOffset + new Vector3(m_marginX, -m_marginY, 0f), * camPosOffset + new Vector3(-m_marginX, -m_marginY, 0f)); */ // handle x margin if (v2Diff.x > m_marginX) { fOffsetX = (v2Diff.x - m_marginX); } else if (v2Diff.x < -m_marginX) { fOffsetX = (v2Diff.x + m_marginX); } // handle y margin if (v2Diff.y > m_marginY) { fOffsetY = (v2Diff.y - m_marginY); } else if (v2Diff.y < -m_marginY) { fOffsetY = (v2Diff.y + m_marginY); } // Prevent backward move if requested if (m_NoBackward) { fOffsetX = Mathf.Max(0f, fOffsetX); } // update dynamic float fAbsOffsetX = Mathf.Abs(fOffsetX); float fSpeedX = m_speed.Evaluate(fAbsOffsetX); camX = Move(camX, camX + fOffsetX, fSpeedX); float fAbsOffsetY = Mathf.Abs(fOffsetY); float fSpeedY = m_speed.Evaluate(fAbsOffsetY); camY = Move(camY, camY + fOffsetY, fSpeedY); // clamp if needed if (m_clampEnabled) { // smooth transition when min/max position has changed if (!m_curMinPos.Equals(m_minPos)) { m_curMinPos.x = Move(m_curMinPos.x, m_minPos.x, m_clampUpdateSpeed); m_curMinPos.y = Move(m_curMinPos.y, m_minPos.y, m_clampUpdateSpeed); } if (!m_curMaxPos.Equals(m_maxPos)) { m_curMaxPos.x = Move(m_curMaxPos.x, m_maxPos.x, m_clampUpdateSpeed); m_curMaxPos.y = Move(m_curMaxPos.y, m_maxPos.y, m_clampUpdateSpeed); } // Effective clamp camX = Mathf.Clamp(camX, m_curMinPos.x, m_maxPos.x); camY = Mathf.Clamp(camY, m_curMinPos.y, m_maxPos.y); } // Final update SetCameraPosition(camX, camY); }