How would one create time as distance between two objects?
I have a player and an object that has to come towards the player with a speed of 1second, 0.85 seconds, 0.7 seconds and so on. However, I'm unaware of doing this. I have a moving 2D map with the speed of -4 to give the illusion of running upwards:
The red triangle on the picture is the object that needs come towards the player, it also has a speed of -4. I created this motion using Time.deltaTime so I would work in realtime. With this logic I believed I had to put the object 4F away from the player to create a 1second interval (desiredSeconds * speed).
PlayerScript
using UnityEngine;
using System.Collections;
public class PlayerScript : MonoBehaviour {
public GameObject obstacle;
public GameObject player;
public float playerDimensionY;
public bool isRight = true;
public bool inAir = false;
public bool mouseClicked = false;
public int flyingSpeed;
float timeStamp1;
float timeStamp2;
bool runOnce = false;
// Use this for initialization
void Start () {
Vector2 sprite_size = GetComponent<SpriteRenderer> ().sprite.rect.size;
Vector2 spriteScale = transform.localScale;
float sizeAndScaleY = sprite_size.y * spriteScale.y;
float player_local_sprite_sizeY = (sizeAndScaleY / GetComponent<SpriteRenderer> ().sprite.pixelsPerUnit) * 0.5F;
playerDimensionY = player_local_sprite_sizeY;
}
// Update is called once per frame
void Update () {
if (isRight == true && mouseClicked == true) {
transform.position += Vector3.right * flyingSpeed * Time.deltaTime;
} else if (isRight == false && mouseClicked == true) {
transform.position += Vector3.left * flyingSpeed * Time.deltaTime;
}
if (Input.GetMouseButtonDown (0) && inAir == false) {
mouseClicked = true;
inAir = true;
if (isRight == true) {
isRight = false;
} else if (isRight == false) {
isRight = true;
}
}
if (GameObject.FindWithTag ("Obstacle") != null && runOnce == false) {
Debug.Log (string.Format("Spawn time: " + timeStamp1));
runOnce = true;
}
timeStamp1 = Time.fixedTime;
timeStamp2 = Time.fixedTime;
}
void OnCollisionEnter2D(Collision2D coll) {
inAir = false;
mouseClicked = false;
}
void OnTriggerEnter2D(Collider2D collTrig) {
Debug.Log (string.Format ("Trigger time: " + timeStamp2));
}
}
ObstacleScript:
using UnityEngine;
using System.Collections;
public class ObstacleScript : MonoBehaviour {
public float constantSpeed;
public float destroyTime;
public float obstacleDimensionY;
private float selfDestroyTime;
// Use this for initialization
void Awake () {
selfDestroyTime = Time.time + destroyTime;
}
void Start() {
Vector2 sprite_size = GetComponent<SpriteRenderer> ().sprite.rect.size;
Vector2 spriteScale = transform.localScale;
float sizeAndScaleY = sprite_size.y * spriteScale.y;
float obstacle_local_sprite_sizeY = (sizeAndScaleY / GetComponent<SpriteRenderer> ().sprite.pixelsPerUnit) * 0.5F;
obstacleDimensionY = obstacle_local_sprite_sizeY;
}
// Update is called once per frame
void Update () {
transform.position += Vector3.up * constantSpeed * Time.deltaTime;
if (Time.time > selfDestroyTime) {
Destroy (gameObject);
}
}
}
ObstacleSpawn:
using UnityEngine;
using System.Collections;
public class ObstacleSpawn : MonoBehaviour {
public PlayerScript pScript;
public ObstacleScript oScript;
public GameObject player;
public GameObject obstacle;
public float randomSpawnMin;
public float randomSpawnMax;
// Use this for initialization
void Start () {
InvokeRepeating ("Spawn", 2F, Random.Range (randomSpawnMin, randomSpawnMax));
}
// Update is called once per frame
void Update () {
}
void Spawn() {
if (pScript.isRight == true && pScript.inAir == false) {
obstacle.transform.localScale = new Vector3 (-1, 1, 1);
Instantiate (obstacle, player.transform.position + new Vector3 (0.05F, 4F, 0), Quaternion.identity);
} else if (pScript.isRight == false && pScript.inAir == false) {
obstacle.transform.localScale = new Vector3 (1, 1, 1);
Instantiate (obstacle, player.transform.position + new Vector3 (-0.05F, 4F, 0), Quaternion.identity);
}
}
}
However, by using timestamps between obstacle spawn and triggering with the character, I got the result of 0.5 interval instead of 1. Because of this I followed to try making it 8F instead of 4F, which should result in my 1 second interval, but it surprisingly gave a 0.86 interval.
I'm very unaware of what I'm missing, but I feel as there might be a flaw in the way I've set up my deltaTime.
Kind regards.
EDIT - Added code:
using UnityEngine;
using System.Collections;
public class ObstacleSpawn : MonoBehaviour {
public PlayerScript pScript;
public ObstacleScript oScript;
public GameObject player;
public GameObject obstacle;
public float randomSpawnMin;
public float randomSpawnMax;
// Use this for initialization
void Start () {
InvokeRepeating ("Spawn", 2F, Random.Range (randomSpawnMin, randomSpawnMax));
}
// Update is called once per frame
void Update () {
var diff = (player.transform.position - obstacle.transform.position);
diff = diff.normalized;
Vector3 speed = new Vector3 (100 * Time.deltaTime, 100 * Time.deltaTime, 100 * Time.deltaTime);
diff.x *= speed.x;
diff.y *= speed.y;
diff.z *= speed.z;
obstacle.transform.position = obstacle.transform.position + diff;
}
void Spawn() {
if (pScript.isRight == true && pScript.inAir == false) {
obstacle.transform.localScale = new Vector3 (-1, 1, 1);
Instantiate (obstacle, obstacle.transform.position, Quaternion.identity);
} else if (pScript.isRight == false && pScript.inAir == false) {
obstacle.transform.localScale = new Vector3 (1, 1, 1);
Instantiate (obstacle, obstacle.transform.position, Quaternion.identity);
}
}
}
var diff = ( Player.transform.position - RedTriangle.transform.position );
diff = diff.normalized;
var speed = Vector3(1*Time.deltaTime,1*Time.deltaTime,1*Time.deltaTime); // <- speed
diff.x *= speed.x;
diff.y *= speed.y;
diff.z *= speed.z;
RedTriangle.transform.position = RedTriangle.transform.position + diff;
Something like this needs to go in Update of a script. ( it will move the triangle towards the player )
Related
I'm developping a 3D game Unity with a squirrel as the player.
I'm struggling with a problem of slopes. I know, there are a bunch of tutorial to go down a slope whithout 'floating in the air while walking' but I didn't find a fine solution. I think it's because of the horizontal animations of the squirrel (maybe). I have tried with addForce, with a modified speed, with gravity... (maybe I implemented it wrong). I know I can check if I'm in the air or not with CharacterController.isGrounded but I can't force the squirrel to stick on the slope while running or walking. I'm sorry by advance if my question is too vague or simple.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System;
public class Squirrel : MonoBehaviour {
Animator squirrel;
public float gravity = 1.0f;
private Vector3 moveDirection = Vector3.zero;
float axisH, axisV;
public static int munitions = 0;
Rigidbody rb;
[SerializeField]
float walkSpeed = 2f, runSpeed = 8f, rotSpeed = 100f, jumpForce = 350;
private bool isJumpKeyDown = false;
[SerializeField] bool isJumping = false;
Animator characterAnimator;
int JumpCount = 0;
public int MaxJumps = 1; //Maximum amount of jumps (i.e. 2 for double jumps)
[SerializeField] GameObject nb_munitions;
CharacterController characterController;
// Use this for initialization
void Start () {
munitions = 0;
squirrel = GetComponent<Animator>();
rb = GetComponentInChildren<Rigidbody>();
characterAnimator = GetComponent<Animator>();
JumpCount = MaxJumps;
characterController = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
GetInput();
nb_munitions.GetComponent<Text>().text = "Glands : " + munitions; //Affichage du score
Move();
}
private void FixedUpdate()
{
if (isJumpKeyDown)
{
squirrel.SetTrigger("jump");
JumpCount -= 1;
isJumpKeyDown = false;
}
}
public void GetInput()
{
axisV = Input.GetAxis("Vertical");
axisH = Input.GetAxis("Horizontal");
}
private void Move()
{
if (characterController.isGrounded)
{
//On the ground
}
else
{
//on the air
}
if (axisV > 0)
{
if (Input.GetKeyDown(KeyCode.LeftControl))
{
transform.position += Vector3.forward * walkSpeed * Time.deltaTime;
squirrel.SetBool("walk", true);
}
else
{
transform.position += Vector3.forward * runSpeed * Time.deltaTime;
squirrel.SetFloat("run", axisV);
squirrel.SetBool("walk", false);
}
}
else
{
squirrel.SetFloat("run", 0);
}
if (axisH != 0 && axisV == 0)
{
squirrel.SetFloat("h", axisH);
}
else
{
squirrel.SetFloat("h", 0);
}
if (axisH != 0)
{
transform.Rotate(Vector3.up * rotSpeed * Time.deltaTime * axisH);
}
if (Input.GetKeyDown(KeyCode.Space))
{
if (JumpCount > 0)
{
isJumpKeyDown = true;
}
}
//Call munitions
if (Input.GetKeyDown(KeyCode.LeftShift))
{
if (Squirrel.munitions > 0)
{
SpawnerScript.Instance.NewSpawnRequest();
munitions--;
}
}
}
}
You can try to get the angle of the slope and make it the pitch for the mesh of the squirrel.
I finally found the problem. My C# script "overwrited" the CharacterController and did not allow the squirrel to go down the slopes. Make sure you follow a move script that "respects" the CharacterController (if you pick one or you'll be fighting windmills).
I'm really new to Unity 3d and I'm trying to make a respawn with my character. It seems that the answer is really easy but I cannot see why my code is not working. If this is a duplicate, let me know.
public Vector3 PointSpawn;
void Start()
{
PointSpawn = gameObject.transform.position;
}
void Update()
{
if (gameObject.transform.position.y < 10)
{
gameObject.transform.position = PointSpawn; // This doesn't work
// gameObject.transform.LookAt(PointSpawn); ---> This DOES work ok
}
}
Parallel Script
public float HorizontalMove;
public float VerticalMove;
private Vector3 playerInput;
public CharacterController player;
public float MoveSpeed;
private Vector3 movePlayer;
public float gravity = 9.8f;
public float fallVelocity;
public float JumpForce;
public bool DoubleJump = false;
public Camera mainCamera;
private Vector3 camForward;
private Vector3 camRight;
void Start()
{
player = GetComponent<CharacterController>();
}
void Update()
{
HorizontalMove = Input.GetAxis("Horizontal");
VerticalMove = Input.GetAxis("Vertical");
playerInput = new Vector3(HorizontalMove, 0, VerticalMove);
playerInput = Vector3.ClampMagnitude(playerInput, 1);
CamDirection();
movePlayer = playerInput.x * camRight + playerInput.z * camForward;
movePlayer = movePlayer * MoveSpeed;
player.transform.LookAt(player.transform.position + movePlayer);
setGravity();
PlayerSkills();
player.Move(movePlayer * Time.deltaTime );
}
void CamDirection()
{
camForward = mainCamera.transform.forward;
camRight = mainCamera.transform.right;
camForward.y = 0;
camRight.y = 0;
camForward = camForward.normalized;
camRight = camRight.normalized;
}
void PlayerSkills()
{
if (player.isGrounded && Input.GetButtonDown("Jump"))
{
fallVelocity = JumpForce;
movePlayer.y = fallVelocity;
DoubleJump = true;
}
else if (player.isGrounded == false && Input.GetButtonDown("Jump") && DoubleJump == true)
{
fallVelocity = JumpForce *2;
movePlayer.y = fallVelocity;
DoubleJump = false;
}
}
void setGravity()
{
if (player.isGrounded)
{
fallVelocity = -gravity * Time.deltaTime;
movePlayer.y = fallVelocity;
}
else
{
fallVelocity -= gravity * Time.deltaTime;
movePlayer.y = fallVelocity;
}
}
Thanks in advance!
Just so the answer to the question is not in the comments:
The original problem is that the assignment gameObject.transform.position = PointSpawn appeared to do nothing. As the line is written properly, the position of this gameObject, must have been getting overwritten elsewhere.
With the addition of OP's movement script, the position of the player was getting overwritten in the movement's Update function. As the other assignment was being done in Update, the call order was not guaranteed to work as intended. The fix is either to assure that the movement Update is run not the frame of the new position assignment or to move the conditional and the assignment to a function that always runs after Update regardless of script execution order, LateUpdate.
I've hit a roadblock where when I move the camera, while moving, the character rotates on the spot however, their direction in where they are heading changes when I update the left thumbstick.
This is odd as updating it in Update doesn't work and forces the character to move in circles and placing it in a bit of script that updates with the right thumbstick is moved, causes the character to rotate and move in very different directions that what I want it to go in. This is temporarily fixed when I move the left thumbstick, updating the character's movement.
The controls for this are: Left Thumbstick - Move player, Right Thumbstick - Move camera, East Button - Jump, North Button - Run.
The goal is to allow the character to rotate themselves as well as their direction when I move the camera rather than them only updating their direction when I move the left thumbstick.
Before the code, these are the packages I'm currently using within Unity that effect this: Cinemachine & Input System.
Here's the movement code that this is effecting:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
using UnityEngine.AI;
using UnityEngine.InputSystem;
public class PlayerMovement : MonoBehaviour
{
private DefaultControls controls;
[Header("Unity General")]
[SerializeField]
private CharacterController controller;
public Transform cameraTransform;
public InputActionReference cameraControl;
[Header("General Settings")]//Player movement.
public bool canMovePlayer;
private Vector2 currentMovementInput;
private Vector3 currentMovement;
private Vector3 currentRunMovement;
private bool isMovementPressed;
private bool isRunPressed;
[Space]//Animator stuff.
public Animator characterAnimator;
private int isWalkingHash;
private int isRunningHash;
[Space]//Player running speed & how fast the player will turn when going left or right.
public float rotationFactorPerFrame = 15.0f;
public float runMultiplier = 3.0f;
[Space]//Default gravity for when the player is falling and gravity for when the player is grounded.
public float gravity = -9.81f;
public float groundedGravity = -0.05f;
[Space]//Playing jumping.
public float initialJumpVelocity;
private bool isJumpPressed = false;
private float maxJumpHeight = 1f;
private float maxJumpTime = 0.5f;
private bool isJumping = false;
private int isJumpingHash;
private bool isJumpAnimating = false;
private void Start()
{
Cursor.lockState = CursorLockMode.Locked;
npcInteraction = GetComponent<NPCInteraction>();
}
private void Awake()
{
controls = new DefaultControls();
controller = GetComponent<CharacterController>();
isWalkingHash = Animator.StringToHash("isWalking");
isRunningHash = Animator.StringToHash("isRunning");
isJumpingHash = Animator.StringToHash("isJumping");
controls.Movement.Walking.started += OnMovementInput;
controls.Movement.Walking.canceled += OnMovementInput;
controls.Movement.Walking.performed += OnMovementInput;
controls.Movement.Run.started += OnRun;
controls.Movement.Run.canceled += OnRun;
controls.Movement.Jump.started += OnJump;
controls.Movement.Jump.canceled += OnJump;
SetupJumpVariables();
}
private void SetupJumpVariables()
{
float timeToApex = maxJumpTime / 2;
gravity = (-2 * maxJumpHeight) / Mathf.Pow(timeToApex, 2);
initialJumpVelocity = (2 * maxJumpHeight) / timeToApex;
}
private void HandleJump()
{
if (!isJumping && controller.isGrounded && isJumpPressed)
{
characterAnimator.SetBool(isJumpingHash, true);
isJumpAnimating = true;
isJumping = true;
currentMovement.y = initialJumpVelocity * 0.5f;
currentRunMovement.y = (initialJumpVelocity + 0.5f) * 0.5f;
}
else if (!isJumpPressed && isJumping && controller.isGrounded)
{
isJumping = false;
}
}
private void OnJump(InputAction.CallbackContext context)
{
isJumpPressed = context.ReadValueAsButton();
}
private void OnRun(InputAction.CallbackContext context)
{
isRunPressed = context.ReadValueAsButton();
}
private void HandleRotation()
{
Vector3 positionToLookAt;
//Change in position our character should point to.
positionToLookAt.x = currentMovement.x;
positionToLookAt.y = 0.0f;
positionToLookAt.z = currentMovement.z;
//Current rotation of our character.
Quaternion currentRotation = transform.rotation;
if (currentMovementInput != Vector2.zero)
{
//Creates a new rotation based on where the player is currently pressing.
float targetAngle = Mathf.Atan2(currentMovementInput.x, currentMovementInput.y) * Mathf.Rad2Deg + cameraTransform.eulerAngles.y;
Quaternion targetRotation = Quaternion.Euler(0f, targetAngle, 0f);
transform.rotation = Quaternion.Lerp(currentRotation, targetRotation, rotationFactorPerFrame * Time.deltaTime);
}
}
private void OnMovementInput(InputAction.CallbackContext context)
{
currentMovementInput = context.ReadValue<Vector2>();
currentMovement = new Vector3(currentMovementInput.x, 0f, currentMovementInput.y);
currentRunMovement.x = currentMovementInput.x * runMultiplier;
currentRunMovement.z = currentMovementInput.y * runMultiplier;
MovementDirection();
isMovementPressed = currentMovementInput.x != 0 || currentMovementInput.y != 0;
}
private void MovementDirection()
{
currentMovement = cameraTransform.forward * currentMovement.z + cameraTransform.right * currentMovement.x;
currentMovement.y = 0f;
currentRunMovement = cameraTransform.forward * currentRunMovement.z + cameraTransform.right * currentRunMovement.x;
currentRunMovement.y = 0f;
}
private void HandleAnimation()
{
bool isWalking = characterAnimator.GetBool(isWalkingHash);
bool isRunning = characterAnimator.GetBool(isRunningHash);
if (isMovementPressed && !isWalking)
{
characterAnimator.SetBool(isWalkingHash, true);
}
else if (!isMovementPressed && isWalking)
{
characterAnimator.SetBool(isWalkingHash, false);
}
if ((isMovementPressed && isRunPressed) && !isRunning)
{
characterAnimator.SetBool(isRunningHash, true);
}
else if ((!isMovementPressed || !isRunPressed) && isRunning)
{
characterAnimator.SetBool(isRunningHash, false);
}
}
private void HandleGravity()
{
bool isFalling = currentMovement.y <= 0.0f;
float fallMultiplier = 1.5f;
if (controller.isGrounded)
{
characterAnimator.SetBool(isJumpingHash, false);
isJumpAnimating = false;
currentMovement.y = groundedGravity;
currentRunMovement.y = groundedGravity;
}
else if (isFalling)
{
float previousYVelocity = currentMovement.y;
float newYVelocity = currentMovement.y + (gravity * fallMultiplier * Time.deltaTime);
float nextYVelocity = (previousYVelocity + newYVelocity) * 0.5f;
currentMovement.y = nextYVelocity;
currentRunMovement.y = nextYVelocity;
}
else
{
float previousYVelocity = currentMovement.y;
float newYVelocity = currentMovement.y + (gravity * Time.deltaTime);
float nextYVelocity = (previousYVelocity + newYVelocity) * 0.5f;
currentMovement.y = nextYVelocity;
currentRunMovement.y = nextYVelocity;
}
}
// Update is called once per frame
public void Update()
{
HandleRotation();
HandleAnimation();
controller.Move(currentMovement * Time.deltaTime);
characterAnimator.SetFloat("Speed", controls.Movement.Walking.ReadValue<Vector2>().magnitude);
if (isRunPressed)
{
controller.Move(currentRunMovement * Time.deltaTime);
}
else
{
controller.Move(currentMovement * Time.deltaTime);
}
HandleGravity();
HandleJump();
if (cameraControl.action.triggered)
{
MovementDirection();
}
LockOnTarget();
Interaction();
}
private void OnEnable()
{
controls.Movement.Enable();
}
private void OnDisable()
{
controls.Movement.Disable();
}
}```
Before diving into your code that has quite deep stuff regarding the camara movement, find this simple way in which a gameObject can face the direction of the camera in a simple way. Just in case it helps. This answers directly your question "How to get a character to turn in the direction of the camera?"
using UnityEngine;
public class LookToCamForward : MonoBehaviour
{
void Start()
{
transform.rotation = Quaternion.LookRotation(Camera.main.transform.forward, Camera.main.transform.up);
}
}
I'm working in Unity 5 Personal edition.. I'm trying to pass float from one script to another, but I get this error:
Assets/CameraTracksPlayer.cs(15,36): error CS1061: Type
ClimberMovement' does not contain a definition forstopCamera' and
no extension method stopCamera' of typeClimberMovement' could be
found (are you missing a using directive or an assembly reference?)
I don't know what am I doing wrong.
Here is my code:
using UnityEngine;
using System.Collections;
public class CameraTracksPlayer : MonoBehaviour {
Transform player;
float isDead;
float offsetY;
// Use this for initialization
void Start () {
GameObject go = GameObject.Find ("MainCamera");
ClimberMovement dying = go.GetComponent <ClimberMovement> ();
float died = dying.stopCamera; //this line gets error!
isDead = died;
GameObject player_go = GameObject.FindGameObjectsWithTag("Player")[0];
if (player_go == null) {
Debug.LogError("Ne dela ker ni taga Player");
return;
}
player = player_go.transform;
offsetY = transform.position.y - player.position.y;
}
// Update is called once per frame
void Update () {
if (player != null && isDead == 1) {
Vector3 pos = transform.position;
}
else if (player != null) {
Vector3 pos = transform.position;
pos.y = player.position.y + offsetY;
transform.position = pos;
}
}
}
This is the code of the script from which I am trying to pass variable:
using UnityEngine;
using System.Collections;
public class ClimberMovement : MonoBehaviour {
Vector3 velocity = Vector3.zero;
public Vector3 gravity;
public Vector3 climbVelocity;
public Vector3 climbVelocityJump;
public float maxSpeed = 5f;
public bool stopCamera = false;
bool didClimb = false;
bool didJump = false;
bool jumping = false;
bool jumping2 = false;
Animator animator;
bool dead = false;
// Use this for initialization
void Start () {
animator = transform.GetComponentInChildren<Animator> ();
animator.SetTrigger("DoClimb");
}
//do gfx input update here
void Update () {
if(Input.GetMouseButtonDown(0)){
didClimb = true;
//didJump = true;
}
if (Input.GetMouseButtonUp(0)) {
jumping2 = true;
}
}
// do physics engine update here
void FixedUpdate () {
velocity += gravity * Time.deltaTime;
if(didClimb == true){
didClimb = false;
jumping = true;
velocity += climbVelocity;
}
else if (jumping2 == true && dead == false) {
jumping = false;
jumping2 = false;
velocity += climbVelocityJump;
}
velocity = Vector3.ClampMagnitude(velocity, maxSpeed);
transform.position += velocity * Time.deltaTime;
if (transform.position.x <= -3.9f) {
transform.position = new Vector3 (-3.9f, transform.position.y, transform.position.z);
if (transform.position.x == -3.9f) {
dead = true;
stopCamera = true;
animator.SetTrigger ("Death");
velocity.y = -5f;
velocity.x = -5f;
}
} else if (transform.position.x >= -1f) {
transform.position = new Vector3 (-1f, transform.position.y, transform.position.z);
}
}
}
1 - You want to cast public bool stopCamera = false; in float died.
Try to change float died with bool died
2 - If you have a NullReferenceException, it means it doesnt find your script in your "MainCamera" gameobject.
Try to add your script "ClimberMovement" in your "MainCamera" gameobject.
Hope it helps you !
My suggestion for your case would be to have a method that returns that value:
public float stopCameraValue(){
return stopCamera;
}
What i guess is that the monobehaviour is preventing you from accessing directly to that variable, thus having an error. Since you are not instatiating the ClimberMovement class in the CameraTracksPlayer class, it may think that it is not instatiated at compile time.
I am making 2D game in Unity.
In this I wanted to add a bullet with a limited number of shots.
The bullet fires in the direction in which the player is but always initiate from the right side even if the player is facing left side. And I have limited the bullet count to 3.
How do I put delay in between the occurrence of the bullets?
1st Script (Bullet)
public class Bullet : MonoBehaviour {
private Player player;
public float speed = 1f;
public int abc = 2;
// Use this for initialization
void Start () {
player = GameObject.Find ("Player").GetComponent<Player> ();
if (player.aa.x == transform.localScale.x)
abc = 1;
}
// Update is called once per frame
public void Update () {
if (abc == 1)
rigidbody2D.velocity = new Vector3 (transform.localScale.x, 0, 1) * speed;
else
rigidbody2D.velocity = new Vector3 (transform.localScale.x, 0, 1) * speed;
}
}
2nd Script (Player)
public class Player : MonoBehaviour {
public float speed = 10f;
public Vector2 maxVelocity = new Vector2(3, 5);
public bool standing;
public float jetSpeed = 15f;
public float airSpeedMultiplier = .3f;
public AudioClip leftFootSound;
public AudioClip rightFootSound;
public AudioClip thudSound;
public AudioClip rocketSound;
public Vector3 aa = new Vector3(1,1,1);
private Animator animator;
private PlayerController controller;
void Start(){
controller = GetComponent<PlayerController> ();
animator = GetComponent<Animator> ();
}
void PlayLeftFootSound(){
if (leftFootSound)
AudioSource.PlayClipAtPoint (leftFootSound, transform.position);
}
void PlayRightFootSound(){
if (rightFootSound)
AudioSource.PlayClipAtPoint (rightFootSound, transform.position);
}
void PlayRocketSound(){
if (!rocketSound || GameObject.Find ("RocketSound"))
return;
GameObject go = new GameObject ("RocketSound");
AudioSource aSrc = go.AddComponent<AudioSource> ();
aSrc.clip = rocketSound;
aSrc.volume = 0.7f;
aSrc.Play ();
Destroy (go, rocketSound.length);
}
void OnCollisionEnter2D(Collision2D target){
if (!standing) {
var absVelX = Mathf.Abs(rigidbody2D.velocity.x);
var absVelY = Mathf.Abs(rigidbody2D.velocity.y);
if(absVelX <= .1f || absVelY <= .1f){
if(thudSound)
AudioSource.PlayClipAtPoint(thudSound, transform.position);
}
}
}
// Update is called once per frame
void Update () {
var forceX = 0f;
var forceY = 0f;
var absVelX = Mathf.Abs (rigidbody2D.velocity.x);
var absVelY = Mathf.Abs (rigidbody2D.velocity.y);
if (absVelY < .2f)
standing = true;
else
standing = false;
if (controller.moving.x != 0) {
if (absVelX < maxVelocity.x) {
forceX = standing ? speed * controller.moving.x : (speed * controller.moving.x * airSpeedMultiplier);
aa = transform.localScale = new Vector3 (forceX > 0 ? 1 : -1, 1, 1);
}
animator.SetInteger ("AnimState", 1);
} else {
animator.SetInteger ("AnimState", 0);
}
if (controller.moving.y > 0) {
PlayRocketSound();
if (absVelY < maxVelocity.y)
forceY = jetSpeed * controller.moving.y;
animator.SetInteger ("AnimState", 2);
} else if (absVelY > 0) {
animator.SetInteger("AnimState", 3);
}
rigidbody2D.AddForce (new Vector2 (forceX, forceY));
}
}
3rd Script (PlayerController)
public class PlayerController : MonoBehaviour {
public Vector2 moving = new Vector2();
public int Bulletlimit = 0;
public int MaxBulletlimit = 3;
public float bulletDelay = 3f;
public bool Gun;
public Bullet bullet;
// Use this for initialization
void Start () {}
// Update is called once per frame
void Update () {
moving.x = moving.y = 0;
if (Input.GetKey ("right")) {
moving.x = 1;
} else if (Input.GetKey ("left")) {
moving.x = -1;
}
if (Input.GetKey ("up")) {
moving.y = 1;
} else if (Input.GetKey ("down")) {
moving.y = -1;
}
if (Input.GetKey ("s")) {
if(Gun){
if(Bulletlimit < MaxBulletlimit)
{
Bullet clone = Instantiate (bullet, transform.position, Quaternion.identity) as Bullet;
Bulletlimit = Bulletlimit + 1;
}
}
}
}
public void BulletCount() {
Bulletlimit = Bulletlimit - 1;
}
}
1) There is an easy method to know where to position your bullets and which direction to shoot. Add a child dummy gameobject under your character that will be used as bullet's initial position. Position it where you want. Now this gameobject moves and rotates relative to your character. Use it's transform.position and transform.rotation.forward when you instantiate bullets.
2) Keep current time when user fired a bullet in a variable like private float lastShotTime;. Update it's value when you fired a bullet lastShotTime = Time.time. Then when user wants to shoot another bullet, check if enough time has passed since last shot if (Time.time > lastShotTime + fireDelay) { Shoot(); }.