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(); }.
Related
I am currently learning C# as I'm studying a Games Design Course at University. I am currently implementing a system where: when the time reaches 0, the game pauses and ends. This works :).
However, at first I tried implementing the code into another script - but doesn't work on that script. This has puzzled me. Here is the code (that works):
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Health : MonoBehaviour
{
private Text TimeText;
public float HealthTimer;
public bool TimeIsRunning;
public GameObject CanvasEnd;
void Start()
{
TimeText = GameObject.Find("Timer").GetComponent<Text>();
TimeIsRunning = true;
CanvasEnd.SetActive(false);
}
void Update()
{
TimeText.text = HealthTimer.ToString("0");
if (TimeIsRunning == true)
{
if (HealthTimer > 0)
{
HealthTimer -= 1 * Time.deltaTime;
}
else
{
Time.timeScale = 0;
CanvasEnd.SetActive(true);
}
if(HealthTimer == 0)
{
TimeIsRunning = false;
HealthTimer = 0;
}
}
This script is directly attached to the timer. But I don't understand why it doesn't work when I implement it into another script (that already controls other game aspects). There were no errors, and everything was declared properly.
The exact same code was put into this script (in void update) and didn't work:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public GameObject Player;
public GameObject PlayerTracker;
public GameObject BlueBottle;
public GameObject GreenBottle;
public GameObject RedBottle;
public GameObject ChestCanvas;
public float Score;
public float ChestScoreK = 0;
private Text HT;
private Text HC;
private Text Port;
private Text TimeText;
float speed = 4;
float rotSpeed = 80;
float rot = 0f;
float gravity = 8;
// Variables counting Blue, Red and Green bottles
public int BBCounter = 0;
public int RBCounter = 0;
public int GBCounter = 0;
public int CCounter = 0;
Vector3 moveDir = Vector3.zero;
CharacterController controller;
Animator anim;
void Start()
{
controller = GetComponent<CharacterController>();
anim = GetComponent<Animator>();
ChestCanvas.SetActive(false);
TimeText = GameObject.Find("Timer").GetComponent<Text>();
}
void Update()
{
//Script was implemented here
if (controller.isGrounded)
{
if (Input.GetKey(KeyCode.W))
{
anim.SetInteger("condition", 1);
moveDir = new Vector3(0, 0, 1);
moveDir *= speed;
moveDir = transform.TransformDirection (moveDir);
}
if (Input.GetKeyUp(KeyCode.W))
{
anim.SetInteger("condition", 0);
moveDir = new Vector3(0, 0, 0);
}
}
rot += Input.GetAxis("Horizontal") * rotSpeed * Time.deltaTime;
transform.eulerAngles = new Vector3(0, rot, 0);
moveDir.y -= gravity * Time.deltaTime;
controller.Move(moveDir * Time.deltaTime);
}
private void FixedUpdate()
{
PlayerTracker.transform.position = Player.transform.position;
}
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "BlueBottle")
{
Debug.Log("BLUE");
BBCounter = BBCounter + 1;
GameObject MasterScriptBlue = GameObject.Find("GameMaster");
MasterScriptBlue.GetComponent<GameMasterScript>();
MasterScriptBlue.GetComponent<GameMasterScript>().BlueBottleCounter = BBCounter;
}
if (other.gameObject.tag == "RedBottle")
{
Debug.Log("RED");
RBCounter = RBCounter + 1;
GameObject MasterScriptRed = GameObject.Find("GameMaster");
MasterScriptRed.GetComponent<GameMasterScript>();
MasterScriptRed.GetComponent<GameMasterScript>().RedBottleCounter = RBCounter;
}
if (other.gameObject.tag == "GreenBottle")
{
Debug.Log("GREEN");
GBCounter = GBCounter + 1;
GameObject MasterScriptGreen = GameObject.Find("GameMaster");
MasterScriptGreen.GetComponent<GameMasterScript>();
MasterScriptGreen.GetComponent<GameMasterScript>().GreenBottleCounter = GBCounter;
}
if(other.gameObject.tag == "CityCollider")
{
GameObject HuntingCity = GameObject.Find("HC");
Destroy(HuntingCity);
ScoringSystem.theScore += 100;
Destroy(other.gameObject);
Debug.Log("Destroyed");
}
if(other.gameObject.tag == "TownCollider")
{
GameObject HuntingTown = GameObject.Find("HT");
Destroy(HuntingTown);
ScoringSystem.theScore += 100;
Destroy(other.gameObject);
Debug.Log("Destroyed");
Debug.Log("Destroyed");
}
if(other.gameObject.tag == "PortCollider")
{
GameObject Port = GameObject.Find("Port");
Destroy(Port);
ScoringSystem.theScore += 100;
Destroy(other.gameObject);
Debug.Log("Destroyed");
}
if(other.gameObject.tag == "Chest")
{
Time.timeScale = 0;
ChestCanvas.SetActive(true);
ChestScoreK += 1;
GameObject MasterScriptChest = GameObject.Find("GameMaster");
MasterScriptChest.GetComponent<GameMasterScript>().ChestScore += ChestScoreK;
Destroy(other.gameObject);
GameObject HealthScript = GameObject.Find("Timer");
HealthScript.GetComponent<Health>().TimeIsRunning = false;
}
}
}
What can I try next?
It's hard to understand the problem from your question, but if you are looking for potential problems in your script then it looks like you are comparing a float to zero here:
if(HealthTimer == 0)
{
TimeIsRunning = false;
HealthTimer = 0;
}
So it is possible that HealthTimer is never exactly zero.
You probbaly want if (HealthTimer <= 0f) instead, or to move that block into the else block of your preceding if statement.
Other differences with the second script are:
the second script is not setting TimeIsRunning = true; in the Start() method,
other methods set Time.timeScale = 0; in the second script (not sure what impact this has, but may be relevant).
Do you have the same 'using' tags at the top of your scripts? The 'text' class only exists in UnityEngine.UI, and not UnityEngine.
https://gyazo.com/0a29918f513316fc4143a5ff76095bd3
This is how it looks visually.
That's my shooting weapon code:
public class Weapon : MonoBehaviour {
public float fireRate = 0;
public float maxDamage = 10;
public LayerMask whatToHit ;
public Transform BulletTrailPrefab;
public Transform MuzzleFlashPrefab;
public Transform HitPrefab;
float timeToSpawnEffect = 0;
public float effectSpawnRate = 10;
float timeToFire = 0;
Transform firePoint;
// Use this for initialization
void Awake () {
firePoint = transform.FindChild("FirePoint");
if(firePoint == null)
{
Debug.LogError("No FirePoint");
}
}
// Update is called once per frame
void Update () {
if(fireRate == 0)
{
if (Input.GetButtonDown("Fire1"))
{
Shoot();
}
}else
{
if(Input.GetButton("Fire1") && Time.time > timeToFire)
{
timeToFire = Time.time + 1 / fireRate;
Shoot();
}
}
}
void Shoot()
{
Vector2 mousePosition = new Vector2(Camera.main.ScreenToWorldPoint(Input.mousePosition).x, Camera.main.ScreenToWorldPoint(Input.mousePosition).y);
Vector2 firePointPosition = new Vector2(firePoint.position.x, firePoint.position.y);
RaycastHit2D hit = Physics2D.Raycast(firePointPosition,mousePosition - firePointPosition,100,whatToHit);
Debug.DrawLine(firePointPosition, (mousePosition - firePointPosition) * 100,Color.cyan);
if(hit.collider != null)
{
Debug.DrawLine(firePointPosition, hit.point, Color.red);
Enemy enemy = hit.collider.GetComponent<Enemy>();
if(enemy != null)
{
enemy.DamageEnemy(Random.Range(maxDamage/2,maxDamage));
// Debug.Log("we hit" + hit.collider.name + " and did: " + maxDamage + " damage");
}
}
if (Time.time >= timeToSpawnEffect)
{
Vector3 hitPos;
Vector3 hitNormal;
if (hit.collider == null)
{
hitPos = (mousePosition - firePointPosition) * 30;
hitNormal = new Vector3(9999, 9999, 9999);
}
else
{
hitPos = hit.point;
hitNormal = hit.normal;
}
Effect(hitPos,hitNormal);
timeToSpawnEffect = Time.time + 1 / effectSpawnRate;
}
}
void Effect(Vector3 hitPos, Vector3 hitNormal)
{
Transform trail = Instantiate(BulletTrailPrefab,firePoint.position,firePoint.rotation) as Transform;
LineRenderer lr = trail.GetComponent<LineRenderer>();
if(lr != null)
{
// Set positions
lr.SetPosition(0, firePoint.position);
lr.SetPosition(1, hitPos);
}
Destroy(trail.gameObject, 0.035f);
if (hitNormal != new Vector3(9999, 9999, 9999))
{
Transform hitParticle = Instantiate(HitPrefab, hitPos, Quaternion.FromToRotation(Vector3.right,hitNormal)) as Transform;
hitParticle.parent = transform.parent;
Destroy(hitParticle.gameObject, 0.3f);
}
Transform clone = Instantiate(MuzzleFlashPrefab, firePoint.position, firePoint.rotation);
clone.parent = firePoint;
float size = Random.Range(0.3f, 0.5f);
clone.localScale = new Vector3(size, size, size);
Destroy(clone.gameObject, 0.02f);
}
}
I've been trying to figure it out what's wrong for hours now. Checked the code just too many times, don't know how to google this problem. Just can't understand why it's hitting everything except that spaceship..
Don't know what other information you might need so tell me if you need something more.
I am developing an offline FPS multiplayer game.
When the Player Rotation value is (0,0,0), then Player moves perfectly in direction. However, my problem is when I rotate the camera using touch input. The player can also rotate his face and press the joystick button for moving the player, but then the player should not move the direction the camera is facing.
My Joystick Script For Player
public class VirtualJoystick : MonoBehaviour, IDragHandler, IPointerUpHandler,IPointerDownHandler {
private Image bgImg;
private Image JoyStickImage;
private Vector3 InputVector;
private void Start(){
bgImg = GetComponent<Image> ();
JoyStickImage = transform.GetChild (0).GetComponent<Image> ();
}
public virtual void OnDrag(PointerEventData ped){
Vector2 pos;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle (bgImg.rectTransform, ped.position, ped.pressEventCamera, out pos)) {
pos.x = (pos.x / bgImg.rectTransform.sizeDelta.x);
pos.y = (pos.y / bgImg.rectTransform.sizeDelta.y);
InputVector = new Vector3 (pos.x * 2 + 1, 0, pos.y * 2 - 1);
InputVector = (InputVector.magnitude > 1) ? InputVector.normalized : InputVector;
JoyStickImage.rectTransform.anchoredPosition = new Vector3 (InputVector.x * (bgImg.rectTransform.sizeDelta.x / 2.5f),
InputVector.z * (bgImg.rectTransform.sizeDelta.y / 2.5f));
}
}
public virtual void OnPointerDown(PointerEventData ped){
OnDrag (ped);
}
public virtual void OnPointerUp(PointerEventData ped){
InputVector = Vector3.zero;
JoyStickImage.rectTransform.anchoredPosition = Vector3.zero;
}
public float Horizontal(){
if (InputVector.x != 0) {
return InputVector.x;
} else {
return Input.GetAxis ("Horizontal");
}
}
public float Vertical(){
if (InputVector.z != 0)
return InputVector.z;
else
return Input.GetAxis ("Vertical");
}
}
My Camera Rotation Script Using Input Touch
public class SwipeCam : MonoBehaviour {
private Vector3 firstPoint;
private Vector3 secondPoint;
private float xAngle = 0.0f;
private float yAngle = 0.0f;
private float xAngleTemp = 0.0f;
private float yAngleTemp = 0.0f;
void Start(){
xAngle = 0.0f;
yAngle = 0.0f;
this.transform.rotation = Quaternion.Euler (yAngle, xAngle, 0.0f);
}
void Update() {
if (Input.touchCount > 0) {
for (int i = 0; i < Input.touchCount; i++) {
Touch touch = Input.GetTouch (i);
if (touch.position.x > Screen.width / 2) {
if (touch.phase == TouchPhase.Began) {
firstPoint = Input.GetTouch (0).position;
xAngleTemp = xAngle;
yAngleTemp = yAngle;
}
if (touch.phase == TouchPhase.Moved) {
secondPoint = Input.GetTouch (0).position;
xAngle = xAngleTemp + (secondPoint.x - firstPoint.x) * 180.0f / Screen.width;
yAngle = yAngleTemp + (secondPoint.y - firstPoint.y) * 180.0f / -Screen.height;
yAngle = Mathf.Clamp (yAngle, -30f, 30f);
this.transform.rotation = Quaternion.Euler (yAngle, xAngle, 0.0f);
this.gameObject.GetComponentInParent<FPScontroller> ().transform.rotation = Quaternion.Euler (0.0f, xAngle, 0.0f);
//this.gameObject.GetComponentInParent<FPScontroller> ().transform.rotation = Quaternion.LookRotation(Vector3.forward,Vector3.up);
}
}
}
}
}
}
Where should I change my code to fix the facing the camera direction to player issue.
That is my Player Script (FPSController.cs)
public class FPScontroller : MonoBehaviour {
// Should this script respond to input?
public bool canControl = true;
public GameObject lookObj; //This is root object that containc MainCamera, Weapons etc.
public GameObject joystick;
bool useFixedUpdate = false;
//Check when run, walk or when can run or not
[HideInInspector]
public bool Running ;
[HideInInspector]
public bool Walking;
[HideInInspector]
public bool canRun;
[HideInInspector]
public Vector3 rorationDir;
//Ladder variables
private GameObject mainCamera = null;
[HideInInspector]
public bool onLadder = false;
//private float ladderHopSpeed = 6.0f;
// For the next variables, #System.NonSerialized tells Unity to not serialize the variable or show it in the inspector view.
// Very handy for organization!
// The current global direction we want the character to move in.
[System.NonSerialized]
public Vector3 inputMoveDirection = Vector3.zero;
// Is the jump button held down? We use this interface instead of checking
// for the jump button directly so this script can also be used by AIs.
[System.NonSerialized]
public bool inputJump = false;
[HideInInspector]
public bool inputRun = false;
[HideInInspector]
public bool inputCrouch = false;
[HideInInspector]
public bool inputProne = false;
[System.Serializable]
public class FPScontrollerMovement {
// The maximum horizontal speed when moving
[HideInInspector]
public float maxForwardSpeed = 10.0f;
[HideInInspector]
public float maxSidewaysSpeed = 10.0f;
[HideInInspector]
public float maxBackwardsSpeed = 10.0f;
//Run and walk variables
public float WalkSpeed = 6.0f;
public float RunSpeed = 9.0f;
//Crouch
public bool canCrouch = true;
public float CrouchSpeed = 3.0f;
public float crouchHeight = 1.5f;
public float crouchSmooth = 8;
//prone
public bool canProne = true;
public float ProneSpeed = 1.5f;
public float proneHeight = 0.7f;
// Curve for multiplying speed based on slope (negative = downwards)
public AnimationCurve slopeSpeedMultiplier = new AnimationCurve(new Keyframe(-90, 1), new Keyframe(0, 1), new Keyframe(90, 0));
// How fast does the character change speeds? Higher is faster.
public float maxGroundAcceleration = 30.0f;
public float maxAirAcceleration = 20.0f;
// The gravity for the character
public float gravity = 10.0f;
public float maxFallSpeed = 20.0f;
[HideInInspector]
public bool enableGravity = true;
// For the next variables, #System.NonSerialized tells Unity to not serialize the variable or show it in the inspector view.
// Very handy for organization!
// The last collision flags returned from controller.Move
[System.NonSerialized]
public CollisionFlags collisionFlags;
// We will keep track of the character's current velocity,
[System.NonSerialized]
public Vector3 velocity;
// This keeps track of our current velocity while we're not grounded
[System.NonSerialized]
public Vector3 frameVelocity = Vector3.zero;
[System.NonSerialized]
public Vector3 hitPoint = Vector3.zero;
[System.NonSerialized]
public Vector3 lastHitPoint = new Vector3(Mathf.Infinity, 0, 0);
}
public FPScontrollerMovement movement = new FPScontrollerMovement();
void Awake () {
if (GetComponent<NetworkView> ().isMine) {
joystick = GameObject.Find ("Joystick");
controller = gameObject.GetComponent<CharacterController>();
standartHeight = controller.height;
/*if(GameObject.FindWithTag("LookObject") != null){
lookObj = GameObject.FindWithTag("LookObject");
}*/
centerY = controller.center.y;
tr = transform;
canRun = true;
canStand = true;
StartCoroutine(setupBools());
}
}
void Update () {
if (GetComponent<NetworkView> ().isMine) {
if (!useFixedUpdate) {
UpdateFunction ();
}
movement.velocity.x = joystick.GetComponent<VirtualJoystick> ().Horizontal () * 5f;
movement.velocity.z = joystick.GetComponent<VirtualJoystick> ().Vertical () * 5f;
//Run input
if (Input.GetAxis ("Vertical") > 0.1f && inputRun && canRun && !onLadder && Walking) {
if (canStand && canStandCrouch) {
OnRunning ();
}
} else {
OffRunning ();
}
//Check when walk or not
if ((movement.velocity.x > 0.01f || movement.velocity.z > 0.01f) || (movement.velocity.x < -0.01f || movement.velocity.z < -0.01f)) {
RunAnimation1 ();
Debug.Log ("Forward");
Walking = true;
}else if (movement.velocity.x > 0.01f) {
Walking = true;
Debug.Log ("Right");
} else if (movement.velocity.x < -0.01f) {
Walking = true;
Debug.Log ("Left");
} else {
RunAnimation ();
Walking = false;
}
if (!canControl)
return;
if (movement.canCrouch) {
if (!onLadder) {
Crouch ();
}
}
if (movement.canProne) {
if (!onLadder) {
Prone ();
}
}
if (onLadder) {
grounded = false;
crouch = false;
prone = false;
}
if (!crouch && !prone && controller.height < standartHeight - 0.01f) {
controller.height = Mathf.Lerp (controller.height, standartHeight, Time.deltaTime / movement.crouchSmooth);
controller.center = new Vector3 (controller.center.x, Mathf.Lerp (controller.center.y, centerY, Time.deltaTime / movement.crouchSmooth), controller.center.z);
lookObj.transform.localPosition = new Vector3 (lookObj.transform.localPosition.x, Mathf.Lerp (lookObj.transform.localPosition.y, standartHeight, Time.deltaTime / movement.crouchSmooth), lookObj.transform.localPosition.z);
}
}
}
void RunAnimation(){
GetComponent<NetworkView> ().RPC ("SysnAnimation", RPCMode.All, 0);
}
void RunAnimation1(){
GetComponent<NetworkView> ().RPC ("SysnAnimation", RPCMode.All, 1);
}
void RunAnimation2(){
GetComponent<NetworkView> ().RPC ("SysnAnimation", RPCMode.All, 2);
}
[RPC]
void SysnAnimation(int index){
if (index == 0) {
GetComponent<Animator> ().Play ("Idle Aim");
} else if (index == 1) {
GetComponent<Animator> ().Play ("Walk Aiming");
} else if (index == 2) {
GetComponent<Animator> ().Play ("Jump");
}
}
void OnRunning (){
Debug.Log ("Run");
Running = true;
movement.maxForwardSpeed = movement.RunSpeed;
movement.maxSidewaysSpeed = movement.RunSpeed;
//Make bigger extra height when player run to increase jump distance
jumping.extraHeight = jumping.baseHeight + 0.15f;
}
void OffRunning (){
Running = false;
if(crouch || prone)
return;
movement.maxForwardSpeed = movement.WalkSpeed;
movement.maxSidewaysSpeed = movement.WalkSpeed;
movement.maxBackwardsSpeed = movement.WalkSpeed/2;
//Change extraheight value to default when player walk
jumping.extraHeight = jumping.baseHeight;
}}
Your camera and joystick code looks fine, but that's not where the problem is.
I'll assume your player movement code looks something like this:
Get input X and Y
Move player right by X, forward by Y
In code form, that might look something like this:
//returns the world-space direction that player wants to move
Vector3 GetDesiredMovement(float inputForward, float inputRight) {
//get a vector pointing to player's right
Vector3 dirRight = Camera.main.transform.right;
dirRight.y = 0f;
dirRight.Normalize();
//get a vector pointing to player's front
Vector3 dirForward = Camera.main.transform.forward;
dirForward.y = 0f;
dirForward.Normalize();
//calculate desired movement based on input
Vector3 desiredMovement = (dirForward * inputForward) + (dirRight * inputRight);
desiredMovement.Normalize();
return desiredMovement;
}
What if "right" and "forward" need to be relative to some other object in the scene, such as a camera? It's easier than you might think: just read those values directly from the camera's transform component.
You could do that by replacing just two lines from the above example:
Vector3 dirRight = Camera.main.transform.right;
Vector3 dirForward = Camera.main.transform.forward;
I solved the problem of basing player movement of the camera's direction.
In my Player's script there are two lines that read joystick input:
movement.velocity.x = joystick.GetComponent<VirtualJoystick> ().Horizontal () * 5f;
movement.velocity.z = joystick.GetComponent<VirtualJoystick> ().Vertical () * 5f;`
I changed them to this:
Vector3 DirectionVector =
new Vector3 (joystick.GetComponent<VirtualJoystick> ().Horizontal (), 0f, joystick.GetComponent<VirtualJoystick> ().Vertical ());
movement.velocity = transform.rotation * DirectionVector * 10f;
Directly add joystick value in movement vector. I just multiply it to the joystick input vector and solve my problem.
Now the player moves based on the player rotation and where the camera is facing.
Thanks everyone for help.
I am moving an object that consists of two cubes: left and right. These cubes are randomly generated on the y-axis upwards.
I am able to move them left and right with no problem, however, when I move one of the cubes left or right they all move.
How am I able to only move one of the cubes when touched only left or right rather than all of them? Here is my code below:
Generate cubes code:
public Transform block;
public Transform player;
private float objectSpawnedTo = 5.0f;
public static float distanceBetweenObjects = 5.0f;
private float nextCheck = 0.0f;
private ArrayList objects = new ArrayList();
void Start () {
maintenance(0.0f);
}
void Update () {
float playerX = player.position.y;
if(playerX > nextCheck)
{
maintenance(playerX);
}
}
private void maintenance(float playerX)
{
nextCheck = playerX + 30;
for (int i = objects.Count-1; i >= 0; i--)
{
Transform blck = (Transform)objects[i];
if(blck.position.y < (transform.position.y - 30))
{
Destroy(blck.gameObject);
objects.RemoveAt(i);
}
}
spawnObjects(5);
}
private void spawnObjects(int howMany)
{
float spawnX = objectSpawnedTo;
for(int i = 0; i<howMany; i++)
{
Vector3 pos = new Vector3(-3.5f,spawnX, 0);
//float firstRandom = Random.Range(-6.0f, 1.0f);
Transform blck = (Transform)Instantiate(block, pos, Quaternion.identity);
//blck.localScale+=new Vector3(firstRandom*2,0,0);
objects.Add(blck);
//pos = new Vector3(0,spawnX, 0);
//blck = (Transform)Instantiate(block, pos, Quaternion.identity);
//blck.localScale +=new Vector3((8.6f-firstRandom)*2,0,0);
//objects.Add(blck);
spawnX = spawnX + distanceBetweenObjects;
}
objectSpawnedTo = spawnX;
}
}
Cube-control code:
public float speed = 5;
// Use this for initialization
void Start () {
}
void Update() {
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved) {
// Get movement of the finger since last frame
Vector3 touchDeltaPosition = Input.GetTouch(0).deltaPosition;
// Move object across XY plane
transform.Translate(touchDeltaPosition.x * speed, 0, 0);
Vector3 boundaryVector = transform.position;
boundaryVector.x = Mathf.Clamp (boundaryVector.x, -5.5f, -2.8f);
transform.position = boundaryVector;
}
}
}
The problem is your cube-control code has no condition in it about which cube is selected : you simply wait for Input.touchCount to be > 0 and then move the cube. So all the cube having this script will move.
I think what you need to do is a raycast to check which cube has been "touched" and then only move it if raycast is successful :
[SerializeField]
private float speed = 0.5f;
private int MAX_TOUCH_COUNT = 5;
private bool[] touched;
protected void Start()
{
touched = new bool[MAX_TOUCH_COUNT];
}
void Update()
{
if (Input.touchCount > 0)
{
for(int i = 0; i < (Input.touchCount <= MAX_TOUCH_COUNT ? Input.touchCount : MAX_TOUCH_COUNT); i++)
{
if(touched[i] && Input.GetTouch(i).phase == TouchPhase.Ended)
{
touched[i] = false;
}
else if (!touched[i] && Input.GetTouch(i).phase == TouchPhase.Began)
{
Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(i).position);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo))
{
if (hitInfo.transform.GetComponentInChildren<*YOUR_CUBE_CONTROL_CLASS_NAME*>() == this)
{
touched[i] = true;
}
}
}
else if (touched[i] && Input.GetTouch(i).phase == TouchPhase.Moved)
{
// Get movement of the finger since last frame
Vector3 touchDeltaPosition = Input.GetTouch(i).deltaPosition;
// Move object across XY plane
transform.Translate(touchDeltaPosition.x * speed, 0, 0);
Vector3 boundaryVector = transform.position;
boundaryVector.x = Mathf.Clamp (boundaryVector.x, -5.5f, -2.8f);
transform.position = boundaryVector;
}
}
else
{
touched = false;
}
}
}
Hope this help,
I made my first game in unity,it is running smoothly.
It has a player and aliens and a map as usual.
sometimes the player gets stuck and does not move forward,
even though the animation of player moving forward runs and his legs keeps moving but still it doesn't move
I have to move in other directions and then it can pass through that point where it got stuck
It happens randomly and not on any fixed spot.
and I am not able to figure out why this is happening
I tried to make the map again but still its there
Any suggestions would be a great help.
ublic 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 PlayerDirection = new Vector3(1,1,1);
public int ArtifactCount = 0;
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(GetComponent<Rigidbody2D>().velocity.x);
var absVelY = Mathf.Abs(GetComponent<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 (GetComponent<Rigidbody2D>().velocity.x);
var absVelY = Mathf.Abs (GetComponent<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);
PlayerDirection = 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);
}
GetComponent<Rigidbody2D>().AddForce (new Vector2 (forceX, forceY));
}
}
Thanks
You should check that the point you are going is not outside your map.
I think that when you are adding forces to the rigidbody you can add "too much" forces and that rigidbody collides with something and after that it get stacked.
Edit:
Check the OnCollisionEnter, OnCollisionStay and Exit also the triggers.
http://docs.unity3d.com/ScriptReference/MonoBehaviour.OnCollisionEnter.html