Trying to run a raycast from my camera to Z = 0 that will hit objects on the TransparentFX layer and temporarily make them transparent as they are likely blocking the view of the player. But the raycast never hits anything.
Camera
https://imgur.com/lyTo8OZ
Tree
https://imgur.com/bgNiMWR
ClearSight.cs
[RequireComponent(typeof(Camera))]
public class ClearSight : MonoBehaviour
{
[SerializeField]
private LayerMask raycastLayers;
// Update is called once per frame
void Update()
{
Vector3 forward = transform.TransformDirection(Vector3.forward) * 10;
Debug.DrawRay(transform.position, forward, Color.green);
RaycastHit2D[] hits = Physics2D.RaycastAll(transform.position, transform.TransformDirection(Vector3.forward), 10f, raycastLayers);
if(hits != null && hits.Length > 0)
{
Debug.Log("Found objects blocking player!");
foreach(RaycastHit2D hit in hits)
{
Debug.Log("Making " + hit.transform.gameObject.name + " transparent!");
AutoTransparent at = hit.transform.GetComponent<AutoTransparent>();
if(at == null)
{
at = hit.transform.gameObject.AddComponent<AutoTransparent>();
}
at.MakeTransparent();
}
}
}
}
AutoTransparent.cs
[RequireComponent(typeof(SpriteRenderer))]
public class AutoTransparent : MonoBehaviour
{
[SerializeField]
private SpriteRenderer[] renderTargets;
[SerializeField]
private float transparentRecoveryTime = 0.1f;
private bool isTransparent = false;
private float transparencyTimer = 0;
private void Update()
{
if (isTransparent)
{
UpdateTransparencyTimer();
}
}
private void UpdateTransparencyTimer()
{
transparencyTimer += Time.deltaTime / transparentRecoveryTime;
if(transparencyTimer >= 1)
{
MakeOpaque();
}
}
public void MakeTransparent()
{
transparencyTimer = 0;
if (!isTransparent)
{
isTransparent = true;
foreach (SpriteRenderer renderer in renderTargets)
{
Color c = renderer.color;
renderer.color = new Color(c.r, c.g, c.b, 0.3f);
}
}
}
public void MakeOpaque()
{
isTransparent = false;
foreach(SpriteRenderer renderer in renderTargets)
{
Color c = renderer.color;
renderer.color = new Color(c.r, c.g, c.b, 1);
}
}
}
Figured it out. I was using RaycastHit2D and Physics2D.RaycastAll, which uses Vector2 parameters so the Z forward variable was being taken out of the equation. Switched up to Box Collider and Physics.RaycastAll and it works great.
Related
I've created a "game" where you can attack enemies with a sword. All damages applies to only one enemy, even if i attack the other one. Also when I destroy the first I get this message
MissingReferenceException: The object of type 'RectTransform' has been destroyed but you are still trying to access it.
How do I fix it?
Here's my code:
Attached to the enemy
public class EnemyHealth : MonoBehaviour
{
private Transform healthBar;
private Transform canvas;
public float maxHealth = 100f;
public float damage = 10f;
float currentHealth;
float barLength;
private void Start()
{
currentHealth = maxHealth;
GameObject gfx = gameObject.transform.Find("GFX").gameObject;
canvas = gfx.transform.Find("Health Bar");
GameObject canv = canvas.gameObject;
healthBar = canv.transform.Find("Green Bar");
barLength = canvas.GetComponent<RectTransform>().rect.width * canvas.localScale.x;
}
public void GetStruck()
{
currentHealth -= damage;
if (currentHealth < 0) currentHealth = 0;
healthBar.localScale = new Vector3(currentHealth / maxHealth, 1f, 1f);
Vector3 p = healthBar.position;
p -= damage / (maxHealth * 2) * barLength * transform.right * -1;
healthBar.position = p;
if(currentHealth == 0)
{
Destroy(gameObject);
}
}
}
And the sword attack
using UnityEngine;
public class SwordAttack : MonoBehaviour
{
public Animator animator;
private EnemyHealth enemyHealth;
private bool isAttacking;
private void Start()
{
enemyHealth = GameObject.FindGameObjectWithTag("Enemy").GetComponent<EnemyHealth>();
}
void Update()
{
if(Input.GetMouseButtonDown(0))
{
isAttacking = true;
animator.Play("swordSwing", -1, 0f);
}
else if(animator.GetCurrentAnimatorStateInfo(0).normalizedTime > 1)
{
isAttacking = false;
}
animator.SetBool("isAttacking", isAttacking);
}
private void OnTriggerEnter(Collider other)
{
if(isAttacking && other.CompareTag("Enemy"))
{
enemyHealth.GetStruck();
}
}
}
private void Start()
{
enemyHealth = GameObject.FindGameObjectWithTag("Enemy").GetComponent<EnemyHealth>();
}
This is your mistake. You are only getting 1 enemy's health at your start method and you are always decreasing from that enemy's health. Instead you can get the hitted enemy's health in your OnTriggerEnter method and apply damage to that enemy.
I was trying to achieve this kind of player ball movement:
Catch Up (Ketchapp)
From my side I have tried and record a video of my current implementation:
CatchUpBallMovementDemo
Two kinds of problem, I was facing:
ball making so much jerk while moving on the plain track that I hope you have clearly noticed in my recorded video
when ball reach left or right edge and you try to swipe its making jerk again rather than remain restricted because clamping related code already added
I have just created a demo project so here I am providing the link for it so personally you can check and provide me a suggestion for making ball movement perfect.
Demo Project Source Link: CatchUpBallDemo
Demo Project SIZE 20MB
What at present making jerk in ball movement that I can't able to decide, whether its following camera jerk, whether ball not moving properly though I have created a plain track for checking purpose.
Ball Inspector Detail:
Complete code added within the working demo project. Share your suggestions with me to solve this.
Code Scripts:
BallController
[RequireComponent (typeof(Rigidbody))]
public class BallController : MonoBehaviour
{
//
private Rigidbody myRigidBody;
private bool isJumper;
private bool allowSpeedIncrease;
private BallInputHandler ballInputHandler;
private float speed;
private float speedMilestone;
private float jumpCounter;
private float scoreElapsedTime;
[SerializeField]
private bool isGrounded;
//
public float ballHorzRange;
public float ballStartSpeed;
public float ballTopSpeed;
public float smoothnessValue;
public float smoothnessX;
private void Awake ()
{
DoOnAwake ();
}
private void DoOnAwake ()
{
ballInputHandler = GetComponent<BallInputHandler> ();
myRigidBody = GetComponent<Rigidbody> ();
speed = ballStartSpeed;
speedMilestone = ballStartSpeed;
}
public void Start ()
{
DoOnStart ();
}
private void DoOnStart ()
{
// assinging player transform to camera to follow
Camera.main.GetComponent<CameraFollow> ().FollowPlayer (transform);
}
void Update ()
{
// slowly increase ball moving speed
if (allowSpeedIncrease) {
speed += Time.deltaTime;
if (speed >= speedMilestone) {
allowSpeedIncrease = false;
speed = speedMilestone;
}
}
}
void FixedUpdate ()
{
// do jumping
if (isJumper) {
jumpCounter++;
if (jumpCounter >= 3) {
isJumper = false;
jumpCounter = 0;
}
myRigidBody.AddForce (Vector3.up * 700f);
}
// applying continuous forward velocity
Vector3 nextVelocity = myRigidBody.velocity;
nextVelocity.x = ballInputHandler.horizontalInput * smoothnessX;
nextVelocity.z = speed;
if (isGrounded) {
nextVelocity.y = 0;
} else if (!isJumper) {
nextVelocity.y -= speed * 0.1f;
}
myRigidBody.velocity = nextVelocity.normalized * speed;
ClampingBallMovement ();
}
// ball horizontal movement limitation
private void ClampingBallMovement ()
{
Vector3 currRigidbodyPos = myRigidBody.position;
if (currRigidbodyPos.x <= -ballHorzRange || currRigidbodyPos.x >= ballHorzRange) {
currRigidbodyPos.x = Mathf.Clamp (currRigidbodyPos.x, -ballHorzRange, ballHorzRange);
myRigidBody.position = currRigidbodyPos;
}
}
void OnTriggerEnter (Collider other)
{
if (other.CompareTag (GameConstants.TAG_TRACK_SPAWNER)) {
GameController.Instance.SpawnPlateform ();
} else if (other.CompareTag (GameConstants.TAG_TRACK_DESTROYER)) {
Destroy (other.transform.parent.gameObject);
}
}
}
BallMeshRolling
public class BallMeshRolling : MonoBehaviour
{
private Vector3 ballLastPosition;
void Start ()
{
ballLastPosition = transform.parent.position;
}
void Update ()
{
// implementation-1
float speed = Vector3.Distance (transform.parent.position, ballLastPosition) * 30f;
transform.RotateAround (transform.position, Vector3.right, speed);
// float dragDifference = (transform.position.x - ballLastPosition.x) * 30f;
// transform.RotateAround (transform.position, Vector3.forward, dragDifference);
ballLastPosition = transform.parent.position;
}
}
CameraFollow
public class CameraFollow : MonoBehaviour
{
//
private Vector3 newPos;
private Vector3 initialPosition;
//
public Transform player;
public Vector3 offSet;
void Awake ()
{
initialPosition = transform.position;
}
void LateUpdate ()
{
if (!player)
return;
newPos = player.position + offSet;
newPos.x = ReMap (newPos.x);
newPos.y = Mathf.Clamp (newPos.y, initialPosition.y, initialPosition.y + 1f);
// transform.position = newPos;
transform.position = Vector3.Lerp (transform.position, newPos, 10f * Time.deltaTime);
}
public void FollowPlayer (Transform target)
{
player = target;
ResetCamera ();
}
public float ReMap (float value, float from1 = -4f, float to1 = 4f, float from2 = -2.5f, float to2 = 2.5f)
{
return (value - from1) / (to1 - from1) * (to2 - from2) + from2;
}
public void ResetCamera ()
{
transform.position = initialPosition;
}
}
I could solve the second problem by simply adding this to BallController.ClampingBallMovement():
private void ClampingBallMovement ()
{
Vector3 currRigidbodyPos = myRigidBody.position;
if (currRigidbodyPos.x <= -ballHorzRange || currRigidbodyPos.x >= ballHorzRange) {
currRigidbodyPos.x = Mathf.Clamp (currRigidbodyPos.x, -ballHorzRange, ballHorzRange);
myRigidBody.position = currRigidbodyPos;
}
// I ADDED THIS
// Clamp the velocity as well
if (currRigidbodyPos.x <= -ballHorzRange && myRigidBody.velocity.x < 0 || currRigidbodyPos.x >= ballHorzRange && myRigidBody.velocity.x > 0)
{
myRigidBody.velocity = new Vector3(0, myRigidBody.velocity.y, myRigidBody.velocity.z);
}
}
you clamped the position but did not clamp the velocity as well.
I could not reproduce the first jerking arround on my PC.
I'm new at programming. I started a Unity3D course at udemy, I already finished the course, but I'm trying to add a buff to my game. What I want is when my player gets that buff, his shot speed inscreases, I tried to do it but im getting this error when I collide with it
NullReferenceException: Object reference not set to an instance of an object
Powerup.OnTriggerEnter2D (UnityEngine.Collider2D other) (at Assets/Galaxy Shooter/Scripts/Powerup.cs:54)
EDIT
Album With usefull images
Player
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour {
public bool canTripleShoot = false;
public bool movSpeedBoost = false;
public bool shield = false;
[SerializeField]
private GameObject _laserPrefabs;
[SerializeField]
private GameObject _tripleShootPrefab;
[SerializeField]
private GameObject _shieldGameObject;
[SerializeField]
private GameObject _explosionPrefab;
[SerializeField]
private float _speed = 5.0f;
[SerializeField]
private GameObject[] _engines;
[SerializeField]
private float _fireRate = 0.25f;
private float _canFire = 0.0f;
public int playerHp = 3;
public int _hitcount = 0;
private UIManager _uiManager;
private GameManager _gameManager;
private SpawnManager _spawnManager;
private AudioSource _audioSource;
// Use this for initialization
void Start () {
_audioSource = GetComponent<AudioSource>();
_spawnManager = GameObject.Find("Spawn_Manager").GetComponent<SpawnManager>();
_uiManager = GameObject.Find("Canvas").GetComponent<UIManager>();
_gameManager = GameObject.Find("GameManager").GetComponent<GameManager>();
transform.position = new Vector3(0, 0, 0);
if(_uiManager != null)
{
_uiManager.UpdateLives(playerHp);
}
if(_spawnManager != null)
{
_spawnManager.StartSpawn();
}
}
// Update is called once per frame
void Update ()
{
Movement();
//ativar ao pressionar espaço ou botão esquerdo do mouse
if (Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButton(0))
{
Shoot();
}
}
//renderização e cooldown dos tiros
private void Shoot()
{
if (Time.time > _canFire)
{
_audioSource.Play();
if (canTripleShoot== true)
{
Instantiate(_tripleShootPrefab, transform.position, Quaternion.identity);
}
else
{
Instantiate(_laserPrefabs, transform.position + new Vector3(0, 0.95f, 0), Quaternion.identity);
}
_canFire = Time.time + _fireRate;
}
}
//calculo de dano
public void Damage()
{
if(shield == true)
{
shield = false;
_shieldGameObject.SetActive(false);
return;
}
_hitcount++;
if(_hitcount == 1)
{
_engines[0].SetActive(true);
}
if(_hitcount == 2)
{
_engines[1].SetActive(true);
}
playerHp--;
_uiManager.UpdateLives(playerHp);
if(playerHp < 1)
{
Instantiate(_explosionPrefab, transform.position, Quaternion.identity);
_gameManager.gameOver = true;
_uiManager.ShowTitleScreen();
Destroy(this.gameObject);
}
}
public void ShieldUp()
{
shield = true;
_shieldGameObject.SetActive(true);
}
//controle da velocidade de movimento e teleporte
private void Movement()
{
float controleHorizontal = Input.GetAxis("Horizontal");
float controleVertical = Input.GetAxis("Vertical");
//velocidade de movimento
if(movSpeedBoost == true)
{
transform.Translate(Vector3.up * _speed * controleVertical * Time.deltaTime * 2.0f);
transform.Translate(Vector3.right * _speed * controleHorizontal * Time.deltaTime * 2.0f);
}else
{
transform.Translate(Vector3.up * _speed * controleVertical * Time.deltaTime);
transform.Translate(Vector3.right * _speed * controleHorizontal * Time.deltaTime);
}
//limita jogar até o centro da tela
if (transform.position.y > 0)
{
transform.position = new Vector3(transform.position.x, 0, 0);
}
//limita jogar até a borda inferior
else if (transform.position.y < -4.2f)
{
transform.position = new Vector3(transform.position.x, -4.2f, 0);
}
//teleporta jogar se sair da tela na horizontal
else if (transform.position.x < -9.45f)
{
transform.position = new Vector3(9.45f, transform.position.y, 0);
}
else if (transform.position.x > 9.45f)
{
transform.position = new Vector3(-9.45f, transform.position.y, 0);
}
}
//duração triple shot
public IEnumerator TripleShotPowerDownRoutine()
{
yield return new WaitForSeconds(5.0f);
canTripleShoot = false;
}
public void TripleShotPowerUpOn()
{
canTripleShoot = true;
StartCoroutine(TripleShotPowerDownRoutine());
}
//duração boost de movimento
public IEnumerator MovSpeedBoostDownRoutine()
{
yield return new WaitForSeconds(5.0f);
movSpeedBoost = false;
}
//ativa boost de movimento e inicia contagem de duração
public void MovSpeedBoost()
{
movSpeedBoost = true;
StartCoroutine(MovSpeedBoostDownRoutine());
}
}
Laser
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Laser : MonoBehaviour {
[SerializeField]
public float _speed = 10.0f;
[SerializeField]
public bool _laserBoost = false;
// Use this for initialization
void Start () {
_laserBoost = false;
if (_laserBoost == true)
{
_speed = 100f;
}
}
// Update is called once per frame
void Update () {
//código gigante e dificil de decifrar ~irony
transform.Translate(Vector3.up * _speed * Time.deltaTime);
if (transform.position.y > 6f)
{
if(transform.parent != null)
{
Destroy(transform.parent.gameObject);
}
Destroy(gameObject);
}
}
public IEnumerator LaserBoostDuration()
{
yield return new WaitForSeconds(10f);
_laserBoost = false;
}
public void LaserBoost()
{
_laserBoost = true;
StartCoroutine(LaserBoostDuration());
}
}
Powerup
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Powerup : MonoBehaviour
{
[SerializeField]
private float _speed = 3.0f;
[SerializeField]
private int powerupID;
[SerializeField]
private AudioClip _clip;
// Update is called once per frame
void Update ()
{
//movimenta o powerup para baixo
transform.Translate(Vector3.down * _speed * Time.deltaTime);
//destroy o power ao sair da tela
if (transform.position.y <-7)
{
Destroy(this.gameObject);
}
}
private void OnTriggerEnter2D(Collider2D other)
{
if(other.tag == "Player")
{
//acessa o player
Player player = other.GetComponent<Player>();
if(player != null)
{
if(powerupID == 0)
{
//ativa tripleshoot
player.TripleShotPowerUpOn();
}
else if(powerupID == 1)
{
//ativa speedboost
player.MovSpeedBoost();
}
else if(powerupID == 2)
{
//ativar shield
player.ShieldUp();
}
else if (powerupID == 3)
{
Laser laser = GameObject.Find("laser").GetComponent<Laser>();
laser.LaserBoost();
}
}
//detroy powerup
AudioSource.PlayClipAtPoint(_clip, transform.position);
Destroy(this.gameObject);
}
}
}
The error is occuring at
laser.LaserBoost();
One of the two:
1) you don't have a object named "laser" in Scene hierarchy;
2) this object exists but doesn't have a component of type Laser attached to it.
Edit: Now that I saw your image, I can confirm it is the case 1) above. You have a Prefab named "laser", but is doesn't exist in the Scene hierarchy. If you want it to come to existence only when needed, you must instantiate the Prefab in scene.
If you want to search for the Prefab by its name, there is a way, but you'll need to have a folder named Resources inside another named Assets... More info here
Instead, I suggest you another approach. First, you will need a reference to your Prefab in some object, depending on the logic of your program. You seem to have a GameManager class, there could be a good place. Add a new field inside there (if it is the case) like this:
[SerializeField]
public Laser laser
// (...)
Then, change the code that generates the error. GameObject.Find tries to find an object that already exists in scene. In your case, you want to instantiate a clone of a Prefab, by passing a reference to it. Something like this:
else if (powerupID == 3)
{
// I don't know for sure how can you access your GameManager in your program. I will suppose your player have a reference to it.
// You shall change the position depending on your game logic
Laser laserClone = (Laser) Instantiate(player.gameManager.laser, player.transform.position, player.transform.rotation);
laserClone.LaserBoost();
}
Now, select the object in Scene that will have the reference (again, I am supposing it is gameManager) to see its inspector, than fill the laser field with a reference to your Prefab that has a Laser component. Just be sure the clone object will be destroyed when it is not needed.
But... To be very honest, I don't think you will get the result you are expecting anyway. If what you want is just faster shoot rate, the way you're trying to do it now seems pretty convoluted to me. Why don't you do it just like the triple shoot you have? Add a flag inside your player, when it is true the fireRate value changes.
I've looked through the code and tried different approaches multiple times, but i just can't seem to get it to work.
It works properly twice, then its stops working properly the third time.
I want 1 object to be instantiated each time, but instead on the third time it spawns 30, which is bad.
I want it to spawn 1 object each time.
So i used this script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Attack : MonoBehaviour {
public Transform playerPos = null;
private float playerDist;
private GameObject projectileEnemyClone;
public GameObject projectileEnemyPrefab;
private float kickBack = 10;
private Rigidbody rb;
private int bulletCount = 0;
private bool canshoot = true;
void Start()
{
rb = GetComponent<Rigidbody>();
}
private void Shoot()
{
if (canshoot == true)
{
projectileEnemyClone = Instantiate(projectileEnemyPrefab, transform.position, Quaternion.identity) as GameObject;
canshoot = false;
}
}
private void Respawn()
{
canshoot = true; ;
}
private void ShootLeft()
{
Shoot();
projectileEnemyClone.transform.position = new Vector3(transform.position.x - 1, transform.position.y, transform.position.z);
projectileEnemyClone.GetComponent<Rigidbody>().AddForce(transform.right * -10);
kickBack *= -1;
rb.AddForce(transform.right * kickBack);
Destroy(projectileEnemyClone, 1);
if (!canshoot)
{
Invoke("Respawn", 2);
}
}
private void ShootRight()
{
Shoot();
projectileEnemyClone.transform.position = new Vector3(transform.position.x + 1, transform.position.y, transform.position.z);
projectileEnemyClone.GetComponent<Rigidbody>().AddForce(transform.right * 10);
rb.AddForce(transform.right * kickBack);
Destroy(projectileEnemyClone, 1);
Invoke("Respawn", 2);
}
void Update () {
playerDist = playerPos.position.x - transform.position.x;
if (playerDist <= (3) && playerDist >= (-3))
{
if (playerDist < (0))
{
Invoke("ShootLeft", 1);
}
else
{
Invoke("ShootRight", 1);
}
}
}
}
Don't use Invoke(), you should create a timer that controls your Shoot() function.
float shootCooldown = 0.1f;
float shootTimer = 0;
bool justShot = false;
void Update()
{
if(!canShoot)
{
shootTimer += Time.deltaTime;
if(shootTimer >= shootCooldown)
{
shootTimer = 0;
canShoot = true;
}
}
}
void Shoot()
{
if(canShoot)
{
Shoot();
canShoot = false;
}
}
Hi i have below cod for my android project and when i look Up and Down and shoot a bullet the bullet shooting direction be wrong where is the problem?
here is a vidoe of my project.
http://www.mediafire.com/file/9xhxvyxds4cyego/2016-11-27_15-07-39.mp4
FirstPerson
using System;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
using UnityStandardAssets.Utility;
using Random = UnityEngine.Random;
namespace UnityStandardAssets.Characters.FirstPerson
{
[RequireComponent(typeof (CharacterController))]
[RequireComponent(typeof (AudioSource))]
public class FirstPersonController : MonoBehaviour
{
[SerializeField] private bool m_IsWalking;
[SerializeField] private float m_WalkSpeed;
[SerializeField] private float m_LookSpeed=4;
[SerializeField] private float m_RunSpeed;
[SerializeField] [Range(0f, 1f)] private float m_RunstepLenghten;
[SerializeField] private float m_JumpSpeed;
[SerializeField] private float m_StickToGroundForce;
[SerializeField] private float m_GravityMultiplier;
[SerializeField] private MouseLook m_MouseLook;
[SerializeField] private bool m_UseFovKick;
[SerializeField] private FOVKick m_FovKick = new FOVKick();
[SerializeField] private bool m_UseHeadBob;
[SerializeField] private CurveControlledBob m_HeadBob = new CurveControlledBob();
[SerializeField] private LerpControlledBob m_JumpBob = new LerpControlledBob();
[SerializeField] private float m_StepInterval;
[SerializeField] private AudioClip[] m_FootstepSounds; // an array of footstep sounds that will be randomly selected from.
[SerializeField] private AudioClip m_JumpSound; // the sound played when character leaves the ground.
[SerializeField] private AudioClip m_LandSound; // the sound played when character touches back on ground.
private Camera m_Camera;
private bool m_Jump;
private float m_YRotation;
private Vector2 m_Input;
private Vector3 m_MoveDir = Vector3.zero;
private CharacterController m_CharacterController;
private CollisionFlags m_CollisionFlags;
private bool m_PreviouslyGrounded;
private Vector3 m_OriginalCameraPosition;
private float m_StepCycle;
private float m_NextStep;
private bool m_Jumping;
private AudioSource m_AudioSource;
public GameObject AK;
// Use this for initialization
private void Start()
{
Instantiate(AK);
m_CharacterController = GetComponent<CharacterController>();
m_Camera = Camera.main;
m_OriginalCameraPosition = m_Camera.transform.localPosition;
m_FovKick.Setup(m_Camera);
m_HeadBob.Setup(m_Camera, m_StepInterval);
m_StepCycle = 0f;
m_NextStep = m_StepCycle/2f;
m_Jumping = false;
m_AudioSource = GetComponent<AudioSource>();
m_MouseLook.Init(transform , m_Camera.transform);
}
// Update is called once per frame
private void Update()
{
RotateView();
// the jump state needs to read here to make sure it is not missed
if (!m_Jump)
{
m_Jump = CrossPlatformInputManager.GetButtonDown("Jump");
}
if (!m_PreviouslyGrounded && m_CharacterController.isGrounded)
{
StartCoroutine(m_JumpBob.DoBobCycle());
PlayLandingSound();
m_MoveDir.y = 0f;
m_Jumping = false;
}
if (!m_CharacterController.isGrounded && !m_Jumping && m_PreviouslyGrounded)
{
m_MoveDir.y = 0f;
}
m_PreviouslyGrounded = m_CharacterController.isGrounded;
}
private void PlayLandingSound()
{
m_AudioSource.clip = m_LandSound;
m_AudioSource.Play();
m_NextStep = m_StepCycle + .5f;
}
private void FixedUpdate()
{
float speed;
GetInput(out speed);
// always move along the camera forward as it is the direction that it being aimed at
Vector3 desiredMove = transform.forward*m_Input.y + transform.right*m_Input.x;
// get a normal for the surface that is being touched to move along it
RaycastHit hitInfo;
Physics.SphereCast(transform.position, m_CharacterController.radius, Vector3.down, out hitInfo,
m_CharacterController.height/2f);
desiredMove = Vector3.ProjectOnPlane(desiredMove, hitInfo.normal).normalized;
m_MoveDir.x = desiredMove.x*speed;
m_MoveDir.z = desiredMove.z*speed;
if (m_CharacterController.isGrounded)
{
m_MoveDir.y = -m_StickToGroundForce;
if (m_Jump)
{
m_MoveDir.y = m_JumpSpeed;
PlayJumpSound();
m_Jump = false;
m_Jumping = true;
}
}
else
{
m_MoveDir += Physics.gravity*m_GravityMultiplier*Time.fixedDeltaTime;
}
m_CollisionFlags = m_CharacterController.Move(m_MoveDir*Time.fixedDeltaTime);
ProgressStepCycle(speed);
UpdateCameraPosition(speed);
}
private void PlayJumpSound()
{
m_AudioSource.clip = m_JumpSound;
m_AudioSource.Play();
}
private void ProgressStepCycle(float speed)
{
if (m_CharacterController.velocity.sqrMagnitude > 0 && (m_Input.x != 0 || m_Input.y != 0))
{
m_StepCycle += (m_CharacterController.velocity.magnitude + (speed*(m_IsWalking ? 1f : m_RunstepLenghten)))*
Time.fixedDeltaTime;
}
if (!(m_StepCycle > m_NextStep))
{
return;
}
m_NextStep = m_StepCycle + m_StepInterval;
PlayFootStepAudio();
}
private void PlayFootStepAudio()
{
if (!m_CharacterController.isGrounded)
{
return;
}
// pick & play a random footstep sound from the array,
// excluding sound at index 0
int n = Random.Range(1, m_FootstepSounds.Length);
m_AudioSource.clip = m_FootstepSounds[n];
m_AudioSource.PlayOneShot(m_AudioSource.clip);
// move picked sound to index 0 so it's not picked next time
m_FootstepSounds[n] = m_FootstepSounds[0];
m_FootstepSounds[0] = m_AudioSource.clip;
}
private void UpdateCameraPosition(float speed)
{
Vector3 newCameraPosition;
if (!m_UseHeadBob)
{
return;
}
if (m_CharacterController.velocity.magnitude > 0 && m_CharacterController.isGrounded)
{
m_Camera.transform.localPosition =
m_HeadBob.DoHeadBob(m_CharacterController.velocity.magnitude +
(speed*(m_IsWalking ? 1f : m_RunstepLenghten)));
newCameraPosition = m_Camera.transform.localPosition;
newCameraPosition.y = m_Camera.transform.localPosition.y - m_JumpBob.Offset();
}
else
{
newCameraPosition = m_Camera.transform.localPosition;
newCameraPosition.y = m_OriginalCameraPosition.y - m_JumpBob.Offset();
}
m_Camera.transform.localPosition = newCameraPosition;
}
private void GetInput(out float speed)
{
// Read input
float horizontal = CrossPlatformInputManager.GetAxisRaw("Horizontal");
float vertical = CrossPlatformInputManager.GetAxisRaw("Vertical");
bool waswalking = m_IsWalking;
#if !MOBILE_INPUT
// On standalone builds, walk/run speed is modified by a key press.
// keep track of whether or not the character is walking or running
m_IsWalking = !Input.GetKey(KeyCode.LeftShift);
#endif
// set the desired speed to be walking or running
speed = m_IsWalking ? m_WalkSpeed : m_RunSpeed;
m_Input = new Vector2(horizontal, vertical);
// normalize input if it exceeds 1 in combined length:
if (m_Input.sqrMagnitude > 1)
{
m_Input.Normalize();
}
// handle speed change to give an fov kick
// only if the player is going to a run, is running and the fovkick is to be used
if (m_IsWalking != waswalking && m_UseFovKick && m_CharacterController.velocity.sqrMagnitude > 0)
{
StopAllCoroutines();
StartCoroutine(!m_IsWalking ? m_FovKick.FOVKickUp() : m_FovKick.FOVKickDown());
}
}
private void RotateView()
{
#if !MOBILE_INPUT
m_MouseLook.LookRotation (transform, m_Camera.transform);
m_Camera.transform.localEulerAngles = new Vector3 (-m_MouseLook.y, m_Camera.transform.localEulerAngles.y,
m_Camera.transform.localEulerAngles.z);
transform.localEulerAngles = new Vector3 (0, m_MouseLook.x, 0);
#else
Vector2 m_MouseLook= new Vector2( CrossPlatformInputManager.GetAxisRaw("HorizontalLook")
,CrossPlatformInputManager.GetAxisRaw("VerticalLook"));
float Camx=m_Camera.transform.localEulerAngles.x;
if((Camx>280 && Camx<=360) ||
(Camx >=0 && Camx<80) ||
(Camx>=80 && Camx<180 && m_MouseLook.y>0) ||
(Camx>180 && Camx<=280 && m_MouseLook.y<0))
{
m_Camera.transform.localEulerAngles += new Vector3 (-m_MouseLook.y*m_LookSpeed, m_Camera.transform.localEulerAngles.y,
m_Camera.transform.localEulerAngles.z);
// AK.transform.localEulerAngles=m_Camera.transform.localEulerAngles;
}
transform.localEulerAngles += new Vector3 (0, m_MouseLook.x*m_LookSpeed, 0);
#endif
m_YRotation = m_MouseLook.y;
}
private void OnControllerColliderHit(ControllerColliderHit hit)
{
Rigidbody body = hit.collider.attachedRigidbody;
//dont move the rigidbody if the character is on top of it
if (m_CollisionFlags == CollisionFlags.Below)
{
return;
}
if (body == null || body.isKinematic)
{
return;
}
body.AddForceAtPosition(m_CharacterController.velocity*0.1f, hit.point, ForceMode.Impulse);
}
}
}
Joystick cod-------------///////////////
using System;
using UnityEngine;
using UnityEngine.EventSystems;
namespace UnityStandardAssets.CrossPlatformInput
{
public class Joystick : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler
{
public enum AxisOption
{
// Options for which axes to use
Both, // Use both
OnlyHorizontal, // Only horizontal
OnlyVertical // Only vertical
}
public int MovementRange = 100;
public AxisOption axesToUse = AxisOption.Both; // The options for the axes that the still will use
public string horizontalAxisName = "Horizontal"; // The name given to the horizontal axis for the cross platform input
public string verticalAxisName = "Vertical"; // The name given to the vertical axis for the cross platform input
Vector3 m_StartPos;
bool m_UseX; // Toggle for using the x axis
bool m_UseY; // Toggle for using the Y axis
CrossPlatformInputManager.VirtualAxis m_HorizontalVirtualAxis; // Reference to the joystick in the cross platform input
CrossPlatformInputManager.VirtualAxis m_VerticalVirtualAxis; // Reference to the joystick in the cross platform input
void OnEnable()
{
CreateVirtualAxes();
}
void Start()
{
m_StartPos = transform.position;
}
void UpdateVirtualAxes(Vector3 value)
{
var delta = m_StartPos - value;
delta.y = -delta.y;
delta /= MovementRange;
if (m_UseX)
{
m_HorizontalVirtualAxis.Update(-delta.x);
}
if (m_UseY)
{
m_VerticalVirtualAxis.Update(delta.y);
}
}
void CreateVirtualAxes()
{
// set axes to use
m_UseX = (axesToUse == AxisOption.Both || axesToUse == AxisOption.OnlyHorizontal);
m_UseY = (axesToUse == AxisOption.Both || axesToUse == AxisOption.OnlyVertical);
// create new axes based on axes to use
if (m_UseX)
{
m_HorizontalVirtualAxis = new CrossPlatformInputManager.VirtualAxis(horizontalAxisName);
CrossPlatformInputManager.RegisterVirtualAxis(m_HorizontalVirtualAxis);
}
if (m_UseY)
{
m_VerticalVirtualAxis = new CrossPlatformInputManager.VirtualAxis(verticalAxisName);
CrossPlatformInputManager.RegisterVirtualAxis(m_VerticalVirtualAxis);
}
}
public void OnDrag(PointerEventData data)
{
Vector3 newPos = Vector3.zero;
if (m_UseX)
{
int delta = (int)(data.position.x - m_StartPos.x);
delta = Mathf.Clamp(delta, - MovementRange, MovementRange);
newPos.x = delta;
}
if (m_UseY)
{
int delta = (int)(data.position.y - m_StartPos.y);
delta = Mathf.Clamp(delta, -MovementRange, MovementRange);
newPos.y = delta;
}
transform.position = new Vector3(m_StartPos.x + newPos.x, m_StartPos.y + newPos.y, m_StartPos.z + newPos.z);
UpdateVirtualAxes(transform.position);
}
public void OnPointerUp(PointerEventData data)
{
transform.position = m_StartPos;
UpdateVirtualAxes(m_StartPos);
}
public void OnPointerDown(PointerEventData data) { }
void OnDisable()
{
// remove the joysticks from the cross platform input
if (m_UseX)
{
m_HorizontalVirtualAxis.Remove();
}
if (m_UseY)
{
m_VerticalVirtualAxis.Remove();
}
}
}
}
Shooting Bullet
#pragma strict
//---------------------------------------------------------
//---------------------------------------------------------
var Mig29_Fulcrum:GameObject;
var AK:Rigidbody;
var muzzel:GameObject;
var bullet:Rigidbody;
var Speed:int=700;
private var Fire:int=0;
private var Shooting:boolean =false;
private var gun:GameObject;
private var fireDelay:float = 0f; // the delay between shots
function Start () {
gun=GameObject.FindWithTag("MyGun");
//var AkGun:Rigidbody=Instantiate(AK,this.transform.position,this.transform.rotation);
//var b:Rigidbody=Instantiate(bullet,this.transform.position,this.transform.rotation);
}
function Update () {
if(Input.GetButtonDown("Fire2"))
{
//gun.GetComponent.<Animation>().Play("Jump");
Shooting=true;
}
if(Input.GetButtonDown("Fire1"))
{
Shooting=false;
}
if(Shooting)
{
AutoFire(0.08f);
}
}
function FireWeapon()
{
Debug.Log("Fire!!!");
GetComponent.<AudioSource>().Play();
gun.GetComponent.<Animation>().Play("GunFire");
var m:GameObject=Instantiate(muzzel,this.transform.position,this.transform.rotation);
m.transform.Rotate(Vector3(-90,0,0));
m.transform.Rotate(Vector3(0,Random.Range(0,180),0));
Destroy(m,0.015);
var b:Rigidbody=Instantiate(bullet,this.transform.position,this.transform.rotation);
b.AddForce(this.transform.forward*Speed);
}
// The function below activates the FireWeapon function
function AutoFire( fireRate:float)
{
if (fireDelay < fireRate)
{
fireDelay += Time.deltaTime;
}
if (fireDelay >= fireRate)
{
FireWeapon();
fireDelay = 0f;
}
}
Judging by the video, the problem is that your bullets are fired based on the position and orientation of the camera, not the gun. This is normally preferable in most first person shooter games (eg. Counter-Strike and similar), but maybe not in your case (since you're using mobile joystick controls).
This behavior is caused by the following code:
var b:Rigidbody=Instantiate(bullet,this.transform.position,this.transform.rotation);
b.AddForce(this.transform.forward*Speed);
Since you're using the position and rotation of this.transform, the script refers to the transform of the camera you attached the script to.
If you wish your game to behave differently, you should consider referring to the transform component of the gun instead (conveniently, in your cased stored in the variable gun):
var b:Rigidbody=Instantiate(bullet,gun.transform.position,gun.transform.rotation);
b.AddForce(gun.transform.forward*Speed);
Note that this might not work if your gun's anchor isn't at the muzzle and its forward vector doesn't point in the direction you want the bullet to come out. In that case, you might want to add to the gun an empty child GameObject that's properly positioned and oriented.