I am trying to create a simple Infinite Runner game on Unity and ran into a problem. The task is to make a ball spawn on the floor and immediately begin to roll to the left towards the Player. I have tried a number of ways to implement it, but it does not seem to work. Here is my most recent attempt:
public class ObstaclePool : MonoBehaviour {
public GameObject columnPrefab;
public GameObject ballPrefab;
public int obstaclePoolSize = 5;
public float spawnRate = 3f;
private GameObject[] obstacles;
private int currentObstacle = 0;
private Vector2 objectPoolPosition = new Vector2(-15, -25);
private float timeSinceLastSpawned;
private float spawnXPosition;
private bool hasCalled = false;
private int dice;
bool beforeBall = false;
// Use this for initialization
void Start () {
timeSinceLastSpawned = 0f;
SetupObstacles();
}
private void SetupObstacles()
{
obstacles = new GameObject[obstaclePoolSize];
for (int i = 0; i < obstaclePoolSize; i++)
{
dice = Random.Range(1, 3);
if (dice == 1)
{
obstacles[i] = (GameObject)Instantiate(columnPrefab, objectPoolPosition, Quaternion.identity);
}
else if (dice == 2)
{
obstacles[i] = (GameObject)Instantiate(ballPrefab, objectPoolPosition, Quaternion.identity);
}
}
}
// Update is called once per frame
void Update () {
timeSinceLastSpawned += Time.deltaTime;
if (GameControl.instance.gameOver == false && timeSinceLastSpawned >= spawnRate)
{
timeSinceLastSpawned = 0f;
if (hasCalled == false)
{
spawnXPosition = 10f;
hasCalled = true;
}
else
{
spawnXPosition = Random.Range(6f, 10f);
}
if (obstacles[currentObstacle].transform.tag == "Ball")
{
spawnXPosition = Random.Range(9f, 10f);
obstacles[currentObstacle].transform.position = new Vector2(spawnXPosition, -1.84f);
ballPrefab.GetComponent<Rigidbody2D>().AddForce(new Vector2(-100f, 0) * 5);
beforeBall = true;
}
else {
if (beforeBall == true)
{
spawnXPosition = Random.Range(9f, 10f);
beforeBall = false;
}
obstacles[currentObstacle].transform.position = new Vector2(spawnXPosition, -7.08f);
Debug.Log(spawnXPosition);
}
currentObstacle++;
if (currentObstacle >= obstaclePoolSize)
{
currentObstacle = 0;
SetupObstacles();
hasCalled = false;
}
}
}
}
For a quick explanation of my code: I have an array of size 5. It holds the obstacles that I have created. When deciding what to put inside the array, I generated a random number (1 or 2). If it's a 1, I put in a column. If it's a 2, I put in a ball. These obstacles are spawned off-screen. Then, I move them in the actual scene after using random number to determine the X position.
This part in particular is where I try to implement it:
if (obstacles[currentObstacle].transform.tag == "Ball")
{
spawnXPosition = Random.Range(9f, 10f);
obstacles[currentObstacle].transform.position = new Vector2(spawnXPosition, -1.84f);
ballPrefab.GetComponent<Rigidbody2D>().AddForce(new Vector2(-100f, 0) * 5);
beforeBall = true;
}
I may have some remnants of stuff that I have been testing out, so some of the code may seem redundant and messy.
I also tried using Translate and Velocity with no success. I also have a ScrollingObject code and a RepeatingBackground code. I placed the ScrollingObject code in the Ball prefab too. (Also, tried taking it out -> ball rolls to the right). These codes come from the Unity tutorial.
RepeatingBackground:
public class RepeatingBackground : MonoBehaviour {
private BoxCollider2D groundCollider;
private float groundHorizontalLength;
// Use this for initialization
private void Awake () {
groundCollider = GetComponent<BoxCollider2D>();
groundHorizontalLength = groundCollider.size.x;
}
// Update is called once per frame
private void Update () {
if (transform.position.x < -groundHorizontalLength)
{
RepositionBackground();
}
}
private void RepositionBackground()
{
Vector2 groundOffSet = new Vector2(groundHorizontalLength * 2f, 0);
transform.position = (Vector2)transform.position + groundOffSet;
}
}
ScrollingObjects:
public class ScrollingObject : MonoBehaviour {
private Rigidbody2D rb2d;
// Use this for initialization
void Start () {
rb2d = GetComponent<Rigidbody2D>();
rb2d.velocity = new Vector2(GameControl.instance.scrollSpeed, 0);
}
// Update is called once per frame
void Update () {
if (GameControl.instance.gameOver == true)
{
rb2d.velocity = Vector2.zero;
}
}
}
It looks like you simply named the wrong object in your first example.
if (obstacles[currentObstacle].transform.tag == "Ball")
{
spawnXPosition = Random.Range(9f, 10f);
obstacles[currentObstacle].transform.position = new Vector2(spawnXPosition, -1.84f);
ballPrefab.GetComponent<Rigidbody2D>().AddForce(new Vector2(-100f, 0) * 5);
beforeBall = true;
}
Notice how here you added the force to the prefab, not an instantiated version of the prefab.
I played around a bit more and got it to work. I just wrote another script that added force to the object. I still do not understand why my original way did not work though.
Related
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.
Unity beginner here, I have a random prefab spawner attached to my game in Unity which randomly spawns 3 prefabs. The problem is, sometimes I get the same prefab like 5 times in a row. How can I prevent the same prefab from spawning twice in a row? Here is my code:
public class randomspawnscript : MonoBehaviour
{
public GameObject prefab1, prefab2, prefab3;
public float spawnRate = 2f;
float nextSpawn = 0f;
int whatToSpawn;
void Update()
{
if (collisionbutton.end != true || gameoverscreenrestart.restartPressed==true || gameovermainmenu.menuPressed==true)
{
if (Time.time > nextSpawn)
{
whatToSpawn = Random.Range(1, 4);
Debug.Log(whatToSpawn);
switch (whatToSpawn)
{
case 1:
Instantiate(prefab1, transform.position, Quaternion.identity);
break;
case 2:
Instantiate(prefab2, transform.position, Quaternion.identity);
break;
case 3:
Instantiate(prefab3, transform.position, Quaternion.identity);
break;
}
nextSpawn = Time.time + spawnRate;
}
}
else
{
return;
}
}
}
A simple way using the Unity's in build Random system is just to create a list of possible generated numbers, and pick a random number from that list, like so:
public class randomspawnscript : MonoBehaviour {
public GameObject prefab1, prefab2, prefab3;
public float spawnRate = 2f;
float nextSpawn = 0f;
int whatToSpawn;
private void Awake() {
// To not get a null ref error when generating the controlled random
// for the first time.
whatToSpawn = 0;
}
void Update() {
if (/* ... */) {
if (Time.time > nextSpawn) {
whatToSpawn = GetControlledRandom();
Debug.Log(whatToSpawn);
switch (whatToSpawn) {
//...
}
nextSpawn = Time.time + spawnRate;
}
} else {
return;
}
}
int GetControlledRandom() {
List<int> possibleChoices = new List<int> {
1, 2, 3
};
// Removes what was spawned before from the possible choices.
possibleChoices.Remove(whatToSpawn);
return possibleChoices[Random.Range(0, possibleChoices.Count)];
}
}
Alternatively, the more simpler way is to just keep generating a number until you get the one you are satisfied with, like so:
int RetardedControlledRandom() {
int generatedNumber;
do {
generatedNumber = Random.Range(1, 4);
} while (generatedNumber == whatToSpawn);
return generatedNumber;
}
This can help if you decide to use the .NET provided System.Random instead.
Also, note that currently most of your values/variables are hardcode.
(Aka it does not dynamically suit to spawning more than 4 types of prefab)
Unity Inspector accepts an array too, so you can make use of that and refactor your code like so:
public class randomspawnscript : MonoBehaviour {
public GameObject[] possibleSpawnPrefabs;
public float spawnRate = 2f;
float nextSpawn = 0f;
int whatToSpawn;
private void Awake() {
whatToSpawn = 0;
}
void Update() {
if (collisionbutton.end != true || gameoverscreenrestart.restartPressed == true || gameovermainmenu.menuPressed == true) {
if (Time.time > nextSpawn) {
whatToSpawn = GetControlledRandom();
Debug.Log(whatToSpawn);
var prefabToSpawn = possibleSpawnPrefabs[whatToSpawn];
Instantiate(prefabToSpawn, transform.position, Quaternion.identity);
nextSpawn = Time.time + spawnRate;
}
} else {
return;
}
}
int GetControlledRandom() {
List<int> possibleChoices = new List<int>();
for (int i = 0; i < possibleSpawnPrefabs.Length; ++i) {
possibleChoices.Add(i);
}
// Removes what was spawned before from the possible choices.
possibleChoices.Remove(whatToSpawn);
return possibleChoices[Random.Range(0, possibleChoices.Count)];
}
}
Well, just make a statement that checks the new randomized Prefab with the previous randomized prefab.
For the lazy code, you can just
GameObject previousPrefab;
and in Randomization, set the previousPrefab to the randomized prefab.
and in next Randomization, check if the previousPrefab == randomizedPrefab, if yes,
randomize again.
^ Also to achieve something like this you have to create a method from your Update() section and call it in Update() so you can call the method again if the previousPrefab is the same as the randomized one.
After I click play the camera stays as it should be, but when I move my character the camera zooms in for no reason
The properties of the camera do not change at all, zoom and everything stays the same. Tryed changing from orthographic to perspective no change, move z axis no change, change scale no change, change resolution and no change, making the camera not a parent and no change it behaves the same as parent and as child
before character walks
after character walks
I dont think that there is something to do with the code but here is the code attached to my character, the camera behaves the same as child and as parent
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class movement : MonoBehaviour
{
public float speed = 5f;
public float jumpSpeed = 8f;
private float movementX = 0f;
private Rigidbody2D rigidBody;
public Transform groundCheckPoint;
public float groundCheckRadius;
public LayerMask groundLayer;
public bool isTouchingGround;
public SpriteRenderer box;
private bool canSpawn = true;
private bool canAnimateWalk = true;
private bool canAnimateIdle = true;
private bool canAnimateJump = true;
private bool stopJump = true;
private int spawningSpeed = 1000;
// Use this for initialization
void Start()
{
rigidBody = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
isTouchingGround = Physics2D.OverlapBox(groundCheckPoint.position,new Vector2(0.9f,0.1f),0f, groundLayer);
movementX = Input.GetAxis("Horizontal");
if (movementX > 0f)
{
if(canAnimateWalk==true && isTouchingGround)
{
canAnimateWalk = false;
StartCoroutine(AnimateWalk());
}
GetComponent<SpriteRenderer>().transform.localScale = new Vector3(2, 2, 1);
rigidBody.velocity = new Vector2(movementX * speed, rigidBody.velocity.y);
}
else if (movementX < 0f)
{
if (canAnimateWalk == true && isTouchingGround)
{
canAnimateWalk = false;
StartCoroutine(AnimateWalk());
}
GetComponent<SpriteRenderer>().transform.localScale = new Vector3(-2, 2, 1);
rigidBody.velocity = new Vector2(movementX * speed, rigidBody.velocity.y);
}
else
{
if(isTouchingGround)
{
StopCoroutine(AnimateWalk());
if(canAnimateIdle==true)
{
canAnimateIdle = false;
StartCoroutine(AnimateIdle());
}
}
rigidBody.velocity = new Vector2(0, rigidBody.velocity.y);
}
if (Input.GetButtonDown("Jump") && isTouchingGround)
{
canAnimateJump = false;
rigidBody.velocity = new Vector2(rigidBody.velocity.x, jumpSpeed);
StartCoroutine(AnimateJump());
}
else if(!isTouchingGround)
{
StopCoroutine(AnimateWalk());
}
}
IEnumerator AnimateJump()
{
Debug.Log("Animating Jump");
int counter = 0;
while (counter < 10)
{
counter++;
GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>("img/j" + counter);
yield return new WaitForSeconds(0.1f);
if(isTouchingGround==true)
{
break;
}
}
while(!isTouchingGround)
{
GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>("img/j10");
yield return new WaitForSeconds(0.1f);
}
GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>("img/i1");
canAnimateWalk = true;
canAnimateJump = true;
}
IEnumerator AnimateIdle()
{
int counter = 0;
while(Input.GetAxis("Horizontal")==0 && counter <10 && rigidBody.velocity.y==0)
{
counter++;
GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>("img/i"+counter);
yield return new WaitForSeconds(0.2f);
}
canAnimateIdle = true;
}
IEnumerator AnimateWalk()
{
int counter = 0;
while (Input.GetAxis("Horizontal")!=0 && counter < 8 && rigidBody.velocity.y==0)
{
counter++;
GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>("img/g" + counter);
yield return new WaitForSeconds(0.08f);
}
canAnimateWalk = true;
}
}
What could it be? I tried everything I think
GetComponent<SpriteRenderer>().transform.localScale = new Vector3(-2, 2, 1);
If your movement script is attached to your "guy" gameobject, then you are changing the (local) scale of it. All children will also scale accordingly.
Since your camera is a child of guy, it will scale and produce the result you see.
Try unparenting the Camera from your guy and create a seperate script that follows your guy and attach that to your Camera.
I solved my problem
The issue was in the character scaling. The camera did not change but the size of the character did making me believe that there was a zoom in.
My character x and y scale is 1 and 1 but I used 2 and 2 scale on move
The scale was used to rotate my character when it moves left and right
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.
I would like to make some lifting platforms in my game, so if the platform went down, the characters can't go over it. I have written a script for it, but for some reason the "lifting up" is not working as intended. It won't go back to its starting place, but it will go a bit below. And for some reason it won't go smoothly to the place where it should, just "teleport" there and done. I thougt multiplying Time.deltaTime with a const will help, but it is the same.
Here is my code, any help would be appreciated:
public class LiftingPlatform : MonoBehaviour {
private Transform lift;
private bool isCanBeLifted;
private float timeToLift;
public float timeNeededToLift = 5f;
private Vector3 startPos;
private Vector3 downPos;
private Vector3 shouldPos;
private bool isDown;
public GameObject[] collidingWalls;
// Use this for initialization
void Start () {
lift = transform;
isCanBeLifted = true;
timeToLift = 0f;
isDown = false;
startPos = transform.position;
downPos = new Vector3(startPos.x, startPos.y - 5f, startPos.z);
}
// Update is called once per frame
void Update () {
timeToLift += Time.deltaTime;
if (timeToLift >= timeNeededToLift) {
if (isCanBeLifted) {
if (isDown) {
shouldPos = Vector3.Lerp(startPos, downPos, Time.deltaTime * 10);
lift.position = new Vector3(shouldPos.x, shouldPos.y, shouldPos.z);
isDown = true;
}
else if (!isDown) {
shouldPos = Vector3.Lerp(downPos, new Vector3(startPos.x, startPos.y, startPos.z), Time.deltaTime * 10);
lift.position = new Vector3(shouldPos.x, shouldPos.y, shouldPos.z);
isDown = false;
}
}
timeToLift = 0;
}
if (!isDown) {
for (int i = 0; i < collidingWalls.Length; i++) {
collidingWalls[i].SetActive(true);
}
}
else if (isDown) {
for (int i = 0; i < collidingWalls.Length; i++) {
collidingWalls[i].SetActive(false);
}
}
}
void OnTriggerEnter(Collider collider) {
if (collider.tag == "Player" || collider.tag == "Enemy") {
isCanBeLifted = false;
}
}
void OnTriggerExit(Collider collider) {
if (collider.tag == "Player" || collider.tag == "Enemy") {
isCanBeLifted = true;
}
}
}
These lifting platforms are a child of another Platforms object.
It doesn't look like you are updating the object's position every frame. You are only checking if the total time passed is greater than the time needed to lift, and then updating the position to a value that is dependent on the delta time (using the Vector3.Lerp function).
What I would do is in the update step, if timeToLift is greater then timeNeededToLift, subtract the latter from the former and invert the value of isDown. Then, in your Vector3.Lerp, make the third argument (timeToLift / timeNeededToLift) instead of (Time.deltaTime * 10). Can you try that and see if it works?
The third argument for Vector3.Lerp is the "blending factor" between the two vectors, 0 is the first vector, 1 is the second, and 0.5 is in between. If the total time is greater than the time needed to lift, but the delta time is not greater than 1, it will get the position of the platform using a blending factor of less than 1, resulting in a platform that didn't move fully.