Im making a platform game with Unity and Im programming with C#. I have a Ball Control script which handles the input and the physics behind its continuous bouncing. I also have a BounceTrigger script which make the ball stop and then make it bounce again. Im trying to implement a respawn with the player should be respawning at the last platform not destructible he has bounced over.
Ball Control Script
public float velocity = 2;
bool alreadyBounced;
bool boost;
float boostMultiplier;
Vector3 boostVelocityAdd;
int fallY = 10;
BounceTrigger platform;
// Update is called once per frame
void Update ()
{
alreadyBounced = false;
float appliedVelocity = velocity * (boost ? boostMultiplier : 1);
Vector3 direction = Vector3.zero;
if(Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.A)) { direction = Vector3.left; rigidbody.AddForce(direction * appliedVelocity, ForceMode.VelocityChange);}
if(Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.D)) { direction = Vector3.right; rigidbody.AddForce(direction * appliedVelocity, ForceMode.VelocityChange);}
if(Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.W)) { direction = Vector3.forward; rigidbody.AddForce(direction * appliedVelocity, ForceMode.VelocityChange);}
if(Input.GetKeyDown(KeyCode.DownArrow) || Input.GetKeyDown(KeyCode.S)) { direction = -Vector3.forward; rigidbody.AddForce(direction * appliedVelocity, ForceMode.VelocityChange); }
if(Input.GetKeyUp(KeyCode.LeftArrow) || Input.GetKeyUp(KeyCode.A)) { direction = -Vector3.left; rigidbody.AddForce(direction * appliedVelocity, ForceMode.VelocityChange); }
if(Input.GetKeyUp(KeyCode.RightArrow) || Input.GetKeyUp(KeyCode.D)){ direction = -Vector3.right; rigidbody.AddForce(direction * appliedVelocity, ForceMode.VelocityChange); }
if(Input.GetKeyUp(KeyCode.UpArrow) || Input.GetKeyUp(KeyCode.W)) { direction = -Vector3.forward; rigidbody.AddForce(direction * appliedVelocity, ForceMode.VelocityChange); }
if(Input.GetKeyUp(KeyCode.DownArrow) || Input.GetKeyUp(KeyCode.S)) { direction = Vector3.forward; rigidbody.AddForce(direction * appliedVelocity, ForceMode.VelocityChange); }
CheckFalling ();
}
public void CheckFalling(){
if(this.transform.position.y < fallY){
Respawn();
}
}
public void Respawn(){
this.transform.position = lastPlatform.transform.position + Vector3.up;
}
public void Bounce(BounceTrigger platform, float upVelocity) {
var reboteGO = (GameObject) GameObject.FindWithTag ("TextoRebote");
var reboteComp = reboteGO.GetComponent<BounceCounter>();
if(!alreadyBounced)
{
if(!platform.isDestructible){
lastPlatform = platform;
}
Debug.Log("Bounce");
alreadyBounced = true;
reboteComp.AumentarRebote();
float downVelocity = rigidbody.velocity.y;
rigidbody.AddForce(Vector3.up * (-downVelocity + upVelocity), ForceMode.VelocityChange);
ResetBoost();
}
}
public void Boost(float multiplier){
if(!boost){
Debug.Log("Boost");
StartCoroutine(BoostCoroutine(multiplier));
}
}
public void ResetBoost(){
if(boost){
Debug.Log("Reset boost");
boost = false;
Vector3 velocityAdd = rigidbody.velocity;
velocityAdd.x = velocityAdd.x / boostMultiplier * (boostMultiplier - 1);
velocityAdd.z = velocityAdd.z / boostMultiplier * (boostMultiplier - 1);
velocityAdd.y = 0;
rigidbody.AddForce(-velocityAdd, ForceMode.VelocityChange);
}
}
public void RestarVida(){
var vidaGO = (GameObject) GameObject.FindWithTag ("TextoVida");
var vidaComp = vidaGO.GetComponent<LifeCounter>();
vidaComp.RestarVida ();
}
IEnumerator BoostCoroutine(float multiplier){
yield return 0;
yield return new WaitForFixedUpdate();
boost = true;
boostMultiplier = multiplier;
Vector3 velocityAdd = rigidbody.velocity;
Debug.Log(velocityAdd);
velocityAdd.x = velocityAdd.x * (boostMultiplier - 1);
velocityAdd.z = velocityAdd.z * (boostMultiplier - 1);
velocityAdd.y = 0;
rigidbody.AddForce(velocityAdd, ForceMode.VelocityChange);
Debug.Log(velocityAdd);
}
Bounce Trigger script:
`
public float upVelocity = 10;
public bool isDestructible = false;
public virtual void OnTriggerEnter(Collider collider){
collider.GetComponent<BallControl>().Bounce(this, upVelocity);
}
when I compile this I get a nullReferenceException
`
You have a global variable BounceTrigger platform; instead of BounceTrigger lastPlatform;, so lastPlatform don't exists anywhere in your code.
Related
The main character from the Unity 3D tutorials that I followed, I believe not from the site, are producing a wobbly left foot. I did not put a foot IK because the issue is not placement. It seems like an origin point thing, but not sure so I turned here for help.
I tried to have the full range of motion of the Mecanim character but was unable to produce foot bones on the rig that seem to work even though I just imported the model and code.
Third Person Character code :
using System;
using System.Collections;
using UnityEngine;
namespace UnityStandardAssets.Characters.ThirdPerson
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CapsuleCollider))]
[RequireComponent(typeof(Animator))]
public class ThirdPersonCharacter : MonoBehaviour
{
[SerializeField] float m_MovingTurnSpeed = 360;
[SerializeField] float m_StationaryTurnSpeed = 180;
[SerializeField] float m_JumpPower = 12f;
[Range(1f, 4f)][SerializeField] float m_GravityMultiplier = 2f;
[SerializeField] float m_RunCycleLegOffset = 0.2f;
[SerializeField] float m_MoveSpeedMultiplier = 1f;
[SerializeField] float m_AnimSpeedMultiplier = 1f;
[SerializeField] float m_GroundCheckDistance = 0.1f;
Rigidbody m_Rigidbody;
Animator m_Animator;
bool m_IsGrounded;
float m_OrigGroundCheckDistance;
const float k_Half = 0.5f;
float m_TurnAmount;
float m_ForwardAmount;
Vector3 m_GroundNormal;
float m_CapsuleHeight;
Vector3 m_CapsuleCenter;
CapsuleCollider m_Capsule;
bool m_Crouching;
void Start()
{
m_Animator = GetComponent<Animator>();
m_Rigidbody = GetComponent<Rigidbody>();
m_Capsule = GetComponent<CapsuleCollider>();
m_CapsuleHeight = m_Capsule.height;
m_CapsuleCenter = m_Capsule.center;
m_Rigidbody.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ;
m_OrigGroundCheckDistance = m_GroundCheckDistance;
}
public void Move(Vector3 move, bool crouch, bool jump)
{
if (move.magnitude > 1f) move.Normalize();
move = transform.InverseTransformDirection(move);
CheckGroundStatus();
move = Vector3.ProjectOnPlane(move, m_GroundNormal);
m_TurnAmount = Mathf.Atan2(move.x, move.z);
m_ForwardAmount = move.z;
ApplyExtraTurnRotation();
if (m_IsGrounded)
{
HandleGroundedMovement(crouch, jump);
}
else
{
HandleAirborneMovement();
}
ScaleCapsuleForCrouching(crouch);
PreventStandingInLowHeadroom();
UpdateAnimator(move);
}
void ScaleCapsuleForCrouching(bool crouch)
{
if (m_IsGrounded && crouch)
{
if (m_Crouching) return;
m_Capsule.height = m_Capsule.height / 2f;
m_Capsule.center = m_Capsule.center / 2f;
m_Crouching = true;
}
else
{
Ray crouchRay = new Ray(m_Rigidbody.position + Vector3.up * m_Capsule.radius * k_Half, Vector3.up);
float crouchRayLength = m_CapsuleHeight - m_Capsule.radius * k_Half;
if (Physics.SphereCast(crouchRay, m_Capsule.radius * k_Half, crouchRayLength, Physics.AllLayers, QueryTriggerInteraction.Ignore))
{
m_Crouching = true;
return;
}
m_Capsule.height = m_CapsuleHeight;
m_Capsule.center = m_CapsuleCenter;
m_Crouching = false;
}
}
void PreventStandingInLowHeadroom()
{
if (!m_Crouching)
{
Ray crouchRay = new Ray(m_Rigidbody.position + Vector3.up * m_Capsule.radius * k_Half, Vector3.up);
float crouchRayLength = m_CapsuleHeight - m_Capsule.radius * k_Half;
if (Physics.SphereCast(crouchRay, m_Capsule.radius * k_Half, crouchRayLength, Physics.AllLayers, QueryTriggerInteraction.Ignore))
{
m_Crouching = true;
}
}
}
void UpdateAnimator(Vector3 move)
{
m_Animator.SetFloat("Forward", m_ForwardAmount, 0.1f, Time.deltaTime);
m_Animator.SetFloat("Turn", m_TurnAmount, 0.1f, Time.deltaTime);
m_Animator.SetBool("Crouch", m_Crouching);
m_Animator.SetBool("OnGround", m_IsGrounded);
if (!m_IsGrounded)
{
m_Animator.SetFloat("Jump", m_Rigidbody.velocity.y);
}
float runCycle =
Mathf.Repeat(
m_Animator.GetCurrentAnimatorStateInfo(0).normalizedTime + m_RunCycleLegOffset, 1);
float jumpLeg = (runCycle < k_Half ? 1 : -1) * m_ForwardAmount;
if (m_IsGrounded)
{
m_Animator.SetFloat("JumpLeg", jumpLeg);
}
if (m_IsGrounded && move.magnitude > 0)
{
m_Animator.speed = m_AnimSpeedMultiplier;
}
else
{
m_Animator.speed = 1;
}
}
void HandleAirborneMovement()
{
Vector3 extraGravityForce = (Physics.gravity * m_GravityMultiplier) - Physics.gravity;
m_Rigidbody.AddForce(extraGravityForce);
m_GroundCheckDistance = m_Rigidbody.velocity.y < 0 ? m_OrigGroundCheckDistance : 0.01f;
}
void HandleGroundedMovement(bool crouch, bool jump)
{
if (jump && !crouch && m_Animator.GetCurrentAnimatorStateInfo(0).IsName("Grounded"))
{
m_Rigidbody.velocity = new Vector3(m_Rigidbody.velocity.x, m_JumpPower, m_Rigidbody.velocity.z);
m_IsGrounded = false;
m_Animator.applyRootMotion = false;
m_GroundCheckDistance = 0.1f;
}
}
void ApplyExtraTurnRotation()
{
float turnSpeed = Mathf.Lerp(m_StationaryTurnSpeed, m_MovingTurnSpeed, m_ForwardAmount);
transform.Rotate(0, m_TurnAmount * turnSpeed * Time.deltaTime, 0);
}
public void OnAnimatorMove()
{
if (m_IsGrounded && Time.deltaTime > 0)
{
Vector3 v = (m_Animator.deltaPosition * m_MoveSpeedMultiplier) / Time.deltaTime;
v.y = m_Rigidbody.velocity.y;
m_Rigidbody.velocity = v;
}
}
void CheckGroundStatus()
{
RaycastHit hitInfo;
Debug.DrawLine(transform.position + (Vector3.up * 0.1f), transform.position + (Vector3.up * 0.1f) + (Vector3.down * m_GroundCheckDistance));
if (Physics.Raycast(transform.position + (Vector3.up * 0.1f), Vector3.down, out hitInfo, m_GroundCheckDistance))
{
m_GroundNormal = hitInfo.normal;
m_IsGrounded = true;
m_Animator.applyRootMotion = true;
}
else
{
m_IsGrounded = false;
m_GroundNormal = Vector3.up;
m_Animator.applyRootMotion = false;
}
}
}
I was coding movement code for my game using this video: Movement code video.
Pardon my garbage code...
void Move(float dir,bool crouchFlag)
{
if(!crouchFlag)
{
if(Physics2D.OverlapCircle(OverheadChecker.position,CelingCirSize,gLayerMask))
{
crouchFlag = true;
}
}
Stand.enabled = !crouchFlag;
Stand2.enabled = !crouchFlag;
Croucher.enabled = crouchFlag;
#region Move & run
if (isGrounded && !crouchFlag && !isOnSlope)
{
Controller.XMove(dir,Speed,rb2d,velPower,acceleration,decceleration);
} else if (isGrounded && isOnSlope && canWalkOnSlope)
{
float TargetSpeed = -dir * Speed;
float TargetSpeedDif = TargetSpeed - rb2d.velocity.x;
float accelerRate = (Mathf.Abs(TargetSpeed) > 0.01f) ? airacceleration : airdecceleration;
float MoveDir = Mathf.Pow(Mathf.Abs(TargetSpeedDif) * accelerRate, velPower) * Mathf.Sign(TargetSpeedDif);
float MoveDirX = MoveDir * slopeNormalPerp.x * MultSlope;
float MoveDirY = MoveDir * slopeNormalPerp.y * MultSlope;
rb2d.AddForce(MoveDirX * Vector2.right);
rb2d.AddForce(MoveDirY * Vector2.up);
}
else if (!isGrounded)
{
float TargetSpeed = dir * Speed;
float TargetSpeedDif = TargetSpeed - rb2d.velocity.x;
float accelerRate = (Mathf.Abs(TargetSpeed) > 0.01f) ? airacceleration : airdecceleration;
float MoveDir = Mathf.Pow(Mathf.Abs(TargetSpeedDif) * accelerRate, velPower) * Mathf.Sign(TargetSpeedDif);
if (rb2d.velocity.y > 0 && !Input.GetButton("Jump"))
{
MoveDir = MoveDir * xJumpForce;
}
rb2d.AddForce(MoveDir * Vector2.right);
}else if (isGrounded && crouchFlag)
{
rb2d.sharedMaterial = noFriction;
float TargetSpeed = dir * CrouchSpeed;
float TargetSpeedDif = TargetSpeed - rb2d.velocity.x;
float accelerRate = (Mathf.Abs(TargetSpeed) > 0.01f) ? acceleration : Crouchdecceleration;
float MoveDir = Mathf.Pow(Mathf.Abs(TargetSpeedDif) * accelerRate, velPower) * Mathf.Sign(TargetSpeedDif);
rb2d.AddForce(MoveDir * Vector2.right);
}
if (isGrounded && Mathf.Abs(HorizontalValue) < 0.01f)
{
float amount = Mathf.Min(Mathf.Abs(rb2d.velocity.x), Mathf.Abs(fricAmount));
amount *= Mathf.Sign(rb2d.velocity.x);
rb2d.AddForce(Vector2.right * -amount, ForceMode2D.Impulse);
}
Vector3 CurrentScale = transform.localScale;
if(Right && dir > 0)
{
transform.localScale = new Vector3(1.4f, 1.4f
, 1);
Right = false;
}
else if (!Right == dir < 0)
{
transform.localScale = new Vector3(-1.4f, 1.4f, 1);
Right = true;
}
#endregion
}
Then I made slopes using a Sprite Shape Controller:
But, the character got stuck on the slopes when going up them, so I used this video for slopes:Fixing slopes video
Irrelevant code is removed:
private void SlopeCheck()
{
checkPos = transform.position - (Vector3)(new Vector2(0.0f, colliderSize.y / 2));
SlopeCheckHorizontal(checkPos);
SlopeCheckVertical(checkPos);
}
private void SlopeCheckHorizontal(Vector2 checkPos)
{
RaycastHit2D slopeHitFront = Physics2D.Raycast(checkPos, transform.right, slopeCheckDistance, gLayerMask);
RaycastHit2D slopeHitBack = Physics2D.Raycast(checkPos, -transform.right, slopeCheckDistance, gLayerMask);
if (slopeHitFront)
{
isOnSlope = true;
slopeSideAngle = Vector2.Angle(slopeHitFront.normal, Vector2.up);
}
else if (slopeHitBack)
{
isOnSlope = true;
slopeSideAngle = Vector2.Angle(slopeHitBack.normal, Vector2.up);
}
else
{
slopeSideAngle = 0.0f;
isOnSlope = false;
}
}
private void SlopeCheckVertical(Vector2 checkPos)
{
RaycastHit2D hit = Physics2D.Raycast(checkPos, Vector2.down, slopeCheckDistance, gLayerMask);
if (hit)
{
slopeNormalPerp = Vector2.Perpendicular(hit.normal).normalized;
slopeDownAngle = Vector2.Angle(hit.normal, Vector2.up);
if(slopeDownAngle != lastSlopeAngle)
{
isOnSlope = true;
}
lastSlopeAngle = slopeDownAngle;
Debug.DrawRay(hit.point, slopeNormalPerp, Color.blue);
Debug.DrawRay(hit.point, hit.normal, Color.green);
}
if (slopeDownAngle > maxSlopeAngle || slopeSideAngle > maxSlopeAngle)
{
canWalkOnSlope = false;
}
else
{
canWalkOnSlope = true;
}
if (isOnSlope && canWalkOnSlope && HorizontalValue == 0.0f)
{
rb2d.sharedMaterial = fullFriction;
}
else
{
rb2d.sharedMaterial = noFriction;
}
}
void Update()
{
if(slopeDownAngle != 0)
{
isOnSlope = true;
} else {
isOnSlope = false;
}
if (CanMove() == true){
HorizontalValue = Input.GetAxisRaw("Horizontal");
}
}
void FixedUpdate()
{
Gcheck();
Move(HorizontalValue, Crouch);
SlopeCheck();
}
Rigidbody>
Mass:0.5
BodyType: Dynamic
LinearDrag: 0
AngularDrag: 0
Gravity: 11
FreezeRotation: Only Z axis
::Friction Is Handled In The Movement Code::
But, when I finished the character got stuck again,
so I tried multiplying the slopeNormalPerp by a variable(MultSlope) and he just bounced up and down if made made it too high and if it was too low nothing happened.
I tried messing with varibles such as the ground-checking circles size, various colliders, the aforementioned MultSlope ,and slopeCheckDistance...
Nothing Helped...
I've been working on this for 7 months(with breaks working on other code) and I have improved greatly in coding, but I still can't fix it.
I tried messing with every relevant variable, watching the video many time, downloading and copy-pasting the code ,and following other tutorials of the slope code, No Dice.
So, I made a basic movement script with wallrunning and wanted to add dashing to it, at first I made parameters for the character to dash and testing it with debug.log worked as intended, but the actual dash command, which was transform.translate(Vector3.forward), didn't work for some reason.
This is the code:
public class PlayerMovement : MonoBehaviour
{
public Transform player;
public CharacterController controller;
public float speed = 12f;
public float baseSpeed;
Vector3 velocity;
public float gravity = -9.81f;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
public Transform wallCheckL;
public Transform wallCheckR;
public float wallDistanceL = -0.4f;
public float wallDistanceR = 0.4f;
public LayerMask wallMask;
public bool touchWallL;
public bool touchWallR;
public float SlideTime = 10f;
public float Ynormal;
public bool isGrounded;
public bool Sprinting;
public bool Crouching;
public bool Sliding;
public bool canDash;
// Start is called before the first frame update
void Start()
{
baseSpeed = speed;
canDash = true;
}
// Update is called once per frame
void Update()
{
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
touchWallL = Physics.CheckSphere(wallCheckL.position, wallDistanceL, wallMask);
touchWallR = Physics.CheckSphere(wallCheckR.position, wallDistanceR, wallMask);
if (isGrounded && velocity.y < 0)
{
velocity.y = -2f;
}
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Vector3 move = transform.right * x + transform.forward * z;
controller.Move(move * speed * Time.deltaTime);
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
if ((isGrounded == true) && Input.GetKeyDown("space"))
{
velocity.y = 10f;
}
if (Input.GetKeyDown(KeyCode.LeftShift))
{
speed = baseSpeed * 1.5f;
Sprinting = true;
}
if (Input.GetKeyUp(KeyCode.LeftShift))
{
speed = baseSpeed;
Sprinting = false;
}
if (Input.GetKeyDown(KeyCode.LeftControl))
{
Crouching = true;
}
if (Input.GetKeyUp(KeyCode.LeftControl))
{
Crouching = false;
}
if (Crouching)
{
transform.localScale = new Vector3(1f, 0.5f, 1f);
} else if (Crouching == false)
{
transform.localScale = new Vector3(1f, 1f, 1f);
}
if (Sprinting && Crouching)
{
Sliding = true;
} else if (Sprinting == false && Crouching == false)
{
Sliding = false;
}
if (Sliding)
{
speed = baseSpeed * 2;
transform.localScale = new Vector3(1f, 0.25f, 1f);
}
Ynormal = transform.localEulerAngles.y;
if (touchWallL)
{
gravity = -4.4f;
transform.localRotation = Quaternion.Euler(0, Ynormal, -20f);
isGrounded = true;
} else if (touchWallR)
{
gravity = -4.4f;
transform.localRotation = Quaternion.Euler(0f, Ynormal, 20f);
isGrounded = true;
}
else
{
gravity = -9.81f;
transform.localRotation = Quaternion.Euler(0f, Ynormal, 0f);
}
if (touchWallR && Input.GetKeyDown(KeyCode.Space))
{
velocity.y = 10f;
transform.position += Vector3.left * Time.deltaTime * 100;
}
if (Input.GetKeyDown(KeyCode.E) && canDash)
{
Dash();
}
}
void Dash()
{
StartCoroutine(dashTimer());
player.transform.Translate(Vector3.forward * Time.deltaTime * speed);
}
IEnumerator dashTimer()
{
canDash = false;
yield return new WaitForSeconds(2f);
canDash = true;
}
}
The requirements themselves work, I did some testing, but the dash itself didn't. I tried controller.move, transform.position += transform.position, even making a game object empty called dash distance and trying to teleport my character there, but none of it worked, all of it resulted in my character just not doing anything when I tried to dash.
This is due that Transform.Translate actually needs to be updated each frame.
Try refactoring a bit like this:
// add another control flag
private bool isDashing = false;
void Update()
{
//...
if (Input.GetKeyDown(KeyCode.E) && canDash)
{
StartCoroutine(dashTimer());
}
if (isDashing)
{
Dash();
}
}
void Dash()
{
player.transform.Translate(Vector3.forward * Time.deltaTime * speed);
}
IEnumerator dashTimer()
{
canDash = false;
isDashing = true;
yield return new WaitForSeconds(2f);
canDash = true;
isDashing = false;
}
So, I started following a tutorial and then added some other things that I needed and everything works fine, even the recoil, but the problem is that it is really choppy, it moves once a frame and it isn't smooth at all (which is what I want) I don't know a lot about programming so I hope you can help me :)
My code:
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Audio;
public class GunController : MonoBehaviour
{
[Header("Gun Setting")]
public float fireRate = 0.1f;
public int clipSize = 30;
public int reservedAmmoCapacity = 270;
//Variables that change throughout the code
bool canShoot;
int _currentAmmoInClip;
int _ammoInReserve;
//Muzzle Flash
public ParticleSystem muzzleFlash;
//Aiming
public Vector3 normalLocalPosition;
public Vector3 aimingLocalPosition;
public float aimSmoothing = 10;
[Header("Mouse Settings")]
public float mouseSensitivity = 1;
Vector2 _currentRotation;
public float weaponSwayAmount = 10;
//Weapon Recoil
public bool randomizeRecoil;
public Vector2 randomRecoilConstraints;
//You only need to assign if randomize recoil is off
public Vector2[] recoilPattern;
//Audio
AudioSource shootingSound;
//Reloading
public float reloadTime = 1.5f;
private void Start()
{
_currentAmmoInClip = clipSize;
_ammoInReserve = reservedAmmoCapacity;
canShoot = true;
shootingSound = GetComponent<AudioSource>();
}
private void Update()
{
DetermineAim();
DetermineRotation();
if (Input.GetMouseButton(0) && canShoot && _currentAmmoInClip > 0)
{
shootingSound.Play();
StartCoroutine(FinishShooting());
muzzleFlash.Play();
canShoot = false;
_currentAmmoInClip--;
StartCoroutine(ShootGun());
}
else if (Input.GetKeyDown(KeyCode.R) && _currentAmmoInClip < clipSize && _ammoInReserve > 0)
{
StartCoroutine(Reload());
}
}
void DetermineRotation()
{
Vector2 mouseAxis = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));
mouseAxis *= mouseSensitivity;
_currentRotation += mouseAxis;
_currentRotation.y = Mathf.Clamp(_currentRotation.y, -90, 90);
transform.localPosition += (Vector3)mouseAxis * weaponSwayAmount / 1000;
transform.root.localRotation = Quaternion.AngleAxis(_currentRotation.x, Vector3.up);
transform.parent.localRotation = Quaternion.AngleAxis(-_currentRotation.y, Vector3.right);
}
void DetermineAim()
{
Vector3 target = normalLocalPosition;
if (Input.GetMouseButton(1)) target = aimingLocalPosition;
Vector3 desiredPosition = Vector3.Lerp(transform.localPosition, target, Time.deltaTime * aimSmoothing);
transform.localPosition = desiredPosition;
}
void DetermineRecoil()
{
transform.localPosition -= Vector3.forward * 0.1f;
if (randomizeRecoil)
{
float xRecoil = Random.Range(-randomRecoilConstraints.x, randomRecoilConstraints.x);
float yRecoil = Random.Range(-randomRecoilConstraints.y, randomRecoilConstraints.y);
Vector2 recoil = new Vector2(xRecoil, yRecoil);
_currentRotation += recoil;
}
else
{
int currentStep = clipSize + 1 - _currentAmmoInClip;
currentStep = Mathf.Clamp(currentStep, 0, recoilPattern.Length - 1);
_currentRotation += recoilPattern[currentStep];
}
}
IEnumerator ShootGun()
{
_currentAmmoInClip -= 1;
DetermineRecoil();
RayCastEnemy();
yield return new WaitForSeconds(fireRate);
canShoot = true;
}
void RayCastEnemy()
{
RaycastHit hit;
if (Physics.Raycast(transform.parent.position, transform.parent.forward, out hit, 1 << LayerMask.NameToLayer("Enemy")))
{
try
{
Debug.Log("Hit an enemy");
Rigidbody rb = hit.transform.GetComponent<Rigidbody>();
rb.constraints = RigidbodyConstraints.None;
rb.AddForce(transform.parent.transform.forward * 50);
}
catch { }
}
}
IEnumerator FinishShooting()
{
yield return new WaitForSeconds(0.3f);
shootingSound.Stop();
}
IEnumerator Reload()
{
canShoot = false;
yield return new WaitForSeconds(reloadTime);
int amountNeeded = clipSize - _currentAmmoInClip;
if (amountNeeded > _ammoInReserve)
{
_currentAmmoInClip += _ammoInReserve;
_ammoInReserve -= amountNeeded;
canShoot = true;
}
else
{
canShoot = false;
_currentAmmoInClip = clipSize;
_ammoInReserve -= amountNeeded;
canShoot = true;
}
}
}
I don't see the function DetermineRecoil() called anywhere in the code, but maybe this solution will work:
let _currentRotation = Vector2.Lerp(_currentRotation, _currentRotation + recoilPattern[currentStep], 10*Time.deltaTime);
It will change the value of _currentRotation smoothly.
I just need to add to it to make the character movement/camera stop moving when the UI is open for the quest, but I don't get where to put the code for the bool variable. And then put to write for the code.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class QuestGiver : MonoBehaviour
{
public Quest quest;
public GameObject questWindow;
public Text titleText;
public Text descriptionText;
public Movement2 player;
public void OpenQuestWindow()
{
questWindow.SetActive(true);
titleText.text = quest.title;
descriptionText.text = quest.description;
}
public void AcceptQuest()
{
questWindow.SetActive(false);
quest.isActive = true;
player.quest = quest;
}
void Start()
{
questWindow = GameObject.Find("QuestWindow");
questWindow.SetActive(false);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement2 : MonoBehaviour
{
[SerializeField] CharacterController controller;
private Vector3 playerVelocity;
private bool groundedPlayer;
public float playerSpeed = 5.0f;
private float jumpHeight = 40f;
public float gravityValue = -9.81f;
public Transform Cam;
public KeyCode jump;
public KeyCode FlyUp;
public KeyCode FlyDown;
public bool ablefly;
private float FlyMax = 250f;
public Quest quest;
public int SoulHP = 30;
private void Start()
{
// add character controller
// controller = gameObject.AddComponent<CharacterController>();
}
void Update()
{
// check if the player is grounded and the vector3.y < 0, if one of this condition is true set back the playerVelocity.y = 0f;
groundedPlayer = controller.isGrounded;
if (groundedPlayer && playerVelocity.y < 0)
{
playerVelocity.y = 0f;
}
Vector3 flyup = new Vector3(0, 50, 0);
Vector3 flydown = new Vector3(0, -50, 0);
Vector3 move = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
// Look for the camera y Rotation and multiply it for the vector 3 move in order make the player direction y as same as the camera.
Vector3 FollowCam = Quaternion.Euler(0, Cam.eulerAngles.y, 0) * move;
controller.Move(FollowCam * Time.deltaTime * playerSpeed);
// makes the player jump by adding a float value to the vector 3 y
if (Input.GetKeyDown(jump) && ablefly == false && groundedPlayer == true)
{
playerVelocity.y += 4f;
//print("Diocane");
}
if (Input.GetKeyDown(FlyUp) && ablefly == true)
{
//flyup = Vector3.ClampMagnitude(flyup, 250f);
gravityValue = 0;
controller.Move(flyup * Time.deltaTime * playerSpeed);
}
if (Input.GetKeyDown(FlyDown) && ablefly == true)
{
//flyup = Vector3.ClampMagnitude(flyup, 250f);
gravityValue = 0;
controller.Move(flydown * Time.deltaTime * playerSpeed);
}
playerVelocity.y += gravityValue * Time.deltaTime;
controller.Move(playerVelocity * Time.deltaTime);
}
public void GoFind()
{
if (quest.isActive)
{
quest.goal.ItemCollected();
if (quest.goal.IsReached())
SoulHP += 30;
}
}
}
You could set the Time.timeScale to 0 when the ui is opened to make anything using deltaTime stop moving.
In the OpenQuestWindow() you would add Time.timeScale = 0;
and in the AcceptQuest() method add Time.timeScale = 1; to set it back to normal
This looks like a Similar question. please check this and ask me if you don't get that.
EDIT:
This is not a tested code, but I hope will give you an idea, of how to proceed.
1- define a public bool variable mybool in Movement2 script
2- call that bool in the QuestGiver Script like this:
void Start() {
questWindow = GameObject.Find("QuestWindow");
questWindow.SetActive(false);
player.mybool = false; // or get the player gameobject by tag...
}
update your Movement2 update function to this:
void Update() {
if (mybool) {
// check if the player is grounded and the vector3.y < 0, if one of this condition is true set back the playerVelocity.y = 0f;
groundedPlayer = controller.isGrounded;
if (groundedPlayer && playerVelocity.y < 0) {
playerVelocity.y = 0 f;
}
Vector3 flyup = new Vector3(0, 50, 0);
Vector3 flydown = new Vector3(0, -50, 0);
Vector3 move = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
// Look for the camera y Rotation and multiply it for the vector 3 move in order make the player direction y as same as the camera.
Vector3 FollowCam = Quaternion.Euler(0, Cam.eulerAngles.y, 0) * move;
controller.Move(FollowCam * Time.deltaTime * playerSpeed);
// makes the player jump by adding a float value to the vector 3 y
if (Input.GetKeyDown(jump) && ablefly == false && groundedPlayer == true) {
playerVelocity.y += 4 f;
//print("Diocane");
}
if (Input.GetKeyDown(FlyUp) && ablefly == true) {
//flyup = Vector3.ClampMagnitude(flyup, 250f);
gravityValue = 0;
controller.Move(flyup * Time.deltaTime * playerSpeed);
}
if (Input.GetKeyDown(FlyDown) && ablefly == true) {
//flyup = Vector3.ClampMagnitude(flyup, 250f);
gravityValue = 0;
controller.Move(flydown * Time.deltaTime * playerSpeed);
}
playerVelocity.y += gravityValue * Time.deltaTime;
controller.Move(playerVelocity * Time.deltaTime);
}
if (!camMove) {
Vector3 move = new Vector3(0, 0, 0);
}
}
Now update that bool in QuestGiver:
public void OpenQuestWindow()
{
questWindow.SetActive(true);
titleText.text = quest.title;
descriptionText.text = quest.description;
player.mybool = false;
}
public void AcceptQuest()
{
questWindow.SetActive(false);
quest.isActive = true;
player.quest = quest;
player.mybool = true;
}