I'm replicating project from this site below:
http://blog.lessmilk.com/unity-spaceshooter-1/
http://blog.lessmilk.com/unity-spaceshooter-2/
But, my bullet does not move forward when the spacebar is pressed. Below are my scripts:
spaceshipScript:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class spaceshipScript : MonoBehaviour {
public GameObject bullet;
// Use this for initialization
void Start () {
}
void Update() {
// Get the rigidbody component
//var r2d = GetComponent("Rigidbody2D");
float speed = 10.0f;
// Move the spaceship when an arrow key is pressed
if (Input.GetKey (KeyCode.RightArrow))
transform.position += Vector3.right * speed * Time.deltaTime;
else if (Input.GetKey (KeyCode.LeftArrow))
transform.position += Vector3.left * speed * Time.deltaTime;
//BULLET
//When spacebar is pressed
if (Input.GetKeyDown(KeyCode.Space)) {
Instantiate(bullet, transform.position, Quaternion.identity);
}
}
}
bulletScript:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class bulletScript : MonoBehaviour {
public int speed = 8;
// Use this for initialization
void Start () {
Input.GetKey (KeyCode.UpArrow);
transform.position += Vector3.right * speed * Time.deltaTime;
}
void OnBecomeInvisible() {
Destroy (gameObject);
}
// Update is called once per frame
void Update () {
}
}
As they are telling you in the comments, you are mixing two different approaches. If you want to modify the position of the bullet using Time.deltaTime you need to move that line to Update()
However if you want to follow the approach of the tutorial, but instead of shooting the bullet from bottom to top, you want to shoot from left to right, you should just change the axis (And dont forget to add a rigid body to the bullet)
// Public variable
public var speed : int = 6;
// Function called once when the bullet is created
function Start () {
// Get the rigidbody component
var r2d = GetComponent("Rigidbody2D");
// Make the bullet move upward
r2d.velocity.x = speed;
}
// Function called when the object goes out of the screen
function OnBecameInvisible() {
// Destroy the bullet
Destroy(gameObject);
}
Related
So I am trying to have my bullet prefab fire in the same direction that my player is facing. Currently if the player faces north that's where the bullet fires, if the player faces south the bullet still fires north shooting straight through the player backwards.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FireRocket : MonoBehaviour
{
public GameObject rocketPrefab;
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
GameObject rocketObject = Instantiate(rocketPrefab);
rocketObject.transform.position = this.transform.position + transform.forward;
}
}
}
The bullet has a box collider and a rigidbody with the script attached. What else do i need to include so that I can have my bullet fire in the same direction my player is facing?
Rocket Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Rocket: MonoBehaviour
{
public float speed = 15f;
public float RocketLife = 10f;
private float RocketLifeTimer;
// Start is called before the first frame update
void Start()
{
RocketLifeTimer = RocketLife;
}
// Update is called once per frame
void Update()
{
transform.position += transform.forward * speed * Time.deltaTime;
RocketLife -= Time.deltaTime;
if (RocketLifeTimer <= 0f)
{
Destroy(this.gameObject);
}
}
}
you need to add transform.rotation = player rotation / or camera rotation
I have a FPSController attached to it: a RigidBody , Animator , NavMeshAgentand two scripts: PlayerController and AgentController.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float speed = 10.0f;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
float translatioin = Input.GetAxis("Vertical") * speed;
float straffe = Input.GetAxis("Horizontal") * speed;
translatioin *= Time.deltaTime;
straffe *= Time.deltaTime;
transform.Translate(straffe, 0, translatioin);
if (Input.GetKeyDown("escape"))
Cursor.lockState = CursorLockMode.None;
}
}
And
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class AgentController : MonoBehaviour
{
public Camera camera;
public NavMeshAgent agent;
public bool agentControl = false;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update ()
{
if (Input.GetMouseButtonDown(0) && agentControl == true)
{
Ray ray = camera.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
agent.SetDestination(hit.point);
}
}
}
}
With the PlayerController I can move around using the keys WSAD and with the AgentController I can click on some point on the terrain and the Agent will walk over there.
When I click for example on one of the big cubes the player is walks over it and stop near it. But then when I'm using the keys WSAD to move back away from the cube the player will keep moving automaticaly back to the cube.
Like a magnet that make the player keep moving to the cube to the same point I clicked on before.
On the FPSCamera I have a script: Just to use the mouse look around.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class camMouseLook : MonoBehaviour
{
Vector2 mouseLook;
Vector2 smoothV;
public float sensitivity = 5.0f;
public float smoothing = 2.0f;
GameObject character;
// Use this for initialization
void Start ()
{
character = this.transform.parent.gameObject;
}
// Update is called once per frame
void Update ()
{
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
var md = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));
md = Vector2.Scale(md, new Vector2(sensitivity * smoothing, sensitivity * smoothing));
smoothV.x = Mathf.Lerp(smoothV.x, md.x, 1f / smoothing);
smoothV.y = Mathf.Lerp(smoothV.y, md.y, 1f / smoothing);
mouseLook += smoothV;
mouseLook.y = Mathf.Clamp(mouseLook.y, -90f, 90f);
transform.localRotation = Quaternion.AngleAxis(-mouseLook.y, Vector3.right);
character.transform.localRotation = Quaternion.AngleAxis(mouseLook.x, Vector3.up);
}
}
I found that while the game is running if I uncheck the NavMeshAgent then I will be able to walk around again fine with the keys but when the NavMeshAgent is on and I click on some cube it will keep moving to that cube even if I'm moving with the keys to other places.
I want to be able either using the AgentController and/or the PlayerControllerwhen the game is running.
UPDATE:
I tried to use OnCollisionEnter and OnCollisionExit
But once I set the move to false again on the OnCollisionExit I'm getting the same problem. The reason is that I set the move to true again in the OnCollisionExit is to be able to click the mouse and move again.
So I'm stuck again.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class AgentController : MonoBehaviour
{
public Camera camera;
public NavMeshAgent agent;
public bool move = true;
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
if (Input.GetMouseButtonDown(0) && move == true)
{
Ray ray = camera.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
agent.SetDestination(hit.point);
}
}
}
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "HitPoint")
{
move = false;
}
}
private void OnCollisionExit(Collision collision)
{
move = true;
}
}
This probably happened because you're setting the destination to positions inside the cubes, so your agent keeps trying to reach them though it's impossible.
First of all, you may want to tell your agent to stop once one of the movement keys is pressed to avoid conflicts. You can use this to stop:
agent.isStopped = true;
agent.velocity = Vector3.zero;
If this is not enought to solve the problem, one workaround would be to put a Nav Mesh Obstacle Component in your cubes, check Carve and rebake your Nav Mesh. This way the agent would stop in the nearest point from the one you set, outside the cube.
A second option would be to check the collision with the cubes, and tell your agent to stop once it collides with the one you clicked.
Hopefully one of these will work for you!
I have this these sprites in my game;
player
circle(1)
circle(2)
circle(3)
circle(4)
circle(5)
circle(6)
The circles are spaced out. I have managed to make the player move from circle(1) to circle(2) when the spacebar is pressed using the code below.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class movement : MonoBehaviour
{
private Vector3 player;
public GameObject position1;
public float speed = 30;
void Update()
{
if (Input.GetKeyDown("space"))
player = position1.transform.position;
player.z = transform.position.z;
transform.position = Vector3.MoveTowards(transform.position, player, speed * Time.deltaTime);
}
}
I need the player to 'zap' to the circles one by one each time the spacebar is pressed, so from circle(1) to circle (2) to circle(3) to circle(4) and so on...
I would also need a way of going beyond circle(6) and to carry on, in theory, to infinity.
I am coding in C# and using Unity 5.5
Thank you in advance
If your goal is to have the player move towards a target, and to have the target change every time the space bar is pressed, you'll need to do a few simple things.
public class Movement : MonoBehaviour
{
// You'll need a list of available targets
public List<Transform> Targets;
// The speed to move at
public float Speed = 30;
// A variable to keep track of the current target
private int _currentTargetIndex = 0;
public void Update()
{
// Get the current target
var target = Targets[_currentTargetIndex];
// Move towards it every frame
transform.position = Vector3.MoveTowards(transform.position, target.position, Speed);
// If the space bar was pressed this frame
if(Input.GetKeyDown("space"))
{
// Select the next target
_currentTargetIndex++;
// If we've run out of targets, wrap around to the beginning
if(_currentTargetIndex >= Targets.Count)
{
_currentTargetIndex = 0;
}
}
}
}
this is a code will work fine . First , you need to have a Rigidbody in your player . ,than add this code :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class movement : MonoBehaviour
{
public GameObject position1;
public GameObject position2;
public GameObject position3;
public GameObject position4;
public GameObject position5;
public GameObject position6;
public int PressedTime;
public float speed = 30;
void Update()
{
if (Input.GetKeyDown("space"))
{
PressedTime += 1;
if (PressedTime == 1)
{
transform.position = Vector3.MoveTowards(transform.position, position1.transform.position, speed);
}
if (PressedTime == 2)
{
transform.position = Vector3.MoveTowards(transform.position, position2.transform.position, speed);
}
if (PressedTime == 3)
{
transform.position = Vector3.MoveTowards(transform.position, position3.transform.position, speed);
}
if (PressedTime == 4)
{
transform.position = Vector3.MoveTowards(transform.position, position4.transform.position, speed);
}
if (PressedTime == 5)
{
transform.position = Vector3.MoveTowards(transform.position, position5.transform.position, speed);
}
if (PressedTime == 6)
{
GetComponent<Rigidbody>().AddForce(position6.transform.position * speed);
}
}
}
}
and set variable position1 to 6 in inspector
if (Input.GetKeyDown("space"))
{
transform.position = Vector3.MoveTowards(transform.position, position1.transform.position, speed);
}
For other circle , you can set variable position2 3 4 5 and so on .
and make 'int PressedTime' , when PressedTime is 6 , turn off the code above and addforce to your gameobject toward the 6th circle .
if my code work , don't forget to accept my answer ! :)
So basicy i need my character to go up when space or mousebutton are pressed. I added rigbody 2d and box colider 2d to my gameobject (player). The problem is when I hit space or mousebuttonit only jump not constantly moving up.
Here is my code:
using UnityEngine;
using System.Collections;
public class PixelMovement : MonoBehaviour {
Vector3 velocity = Vector3.zero;
public Vector3 PressVelocity;
public float maxSpeed = 5f;
public float fowardSpeed = 1f;
public float jumpForce;
bool didPress = false;
// Use this for initialization
void Start () {
}
//Do Graphic & Input updates
void Update()
{
if (Input.GetKey(KeyCode.Space) || Input.GetMouseButton(0))
{
didPress = true;
}
}
//Do physics engine updates here
void FixedUpdate()
{
velocity.x = fowardSpeed;
if (didPress == true)
{
didPress = false;
velocity += PressVelocity * Time.deltaTime *jumpForce;
}
velocity = Vector3.ClampMagnitude(velocity, maxSpeed);
transform.position += velocity * Time.deltaTime;
}
}
Ok this works for me. Thanks everyone for help :)
using UnityEngine;
using System.Collections;
public class PixelMovement : MonoBehaviour {
public float playerSpeed;
public Vector3 gravity;
public float maxSpeed = 5f;
Vector3 velocity = Vector3.zero;
public float fowardSpeed = 1f;
bool didPress = false;
void Update()
{
if (Input.GetKey(KeyCode.Space) || Input.GetMouseButton(0))
{
didPress = true;
}
else
{
didPress = false;
}
}
void FixedUpdate()
{
velocity.x = fowardSpeed;
transform.position += velocity * Time.deltaTime;
if (didPress == true)
{
float amntToMove1 = playerSpeed * Time.deltaTime;
transform.Translate(Vector3.up * amntToMove1);
}
velocity = Vector3.ClampMagnitude(velocity, maxSpeed);
transform.position += velocity * Time.deltaTime;
}
}
If you are using gravity and RigitBody2D's mass. I recomend you use the RigitBody2D.Addforce() method to jump your caracter, because if you just change the caracter position, the gravity will turn down him to the ground inmediately
This code creates the effect of a "rocketman" that takes off when the user keeps the spacebar pressed:
using UnityEngine;
using System.Collections;
public class jumpAntigravity : MonoBehaviour {
Vector2 upForce;
void Start () {
//Up force set to double of gravity
upForce = new Vector2(0, 9.8f*2);
}
void Update () {
if (Input.GetKey(KeyCode.Space))
{
print("Spacebar is down");
GetComponent<Rigidbody2D>().AddForce(upForce);
}
}
}
if (Input.GetKey(KeyCode.Space) || Input.GetMouseButton(0))
{
didPress = true;
}
else
{
didPress = false;
}
and remove didPress = false; from FixedUpdate() function
EDIT: Ok, wait, I just noticed you update transform.position in FixedUpdate() which is not really a good idea. When you do so you basically teleport your object from one position to another ignoring all kinds of physics (which probably is the reason you are using FixedUpdate()). With your script colliding with other objects will give you weird results. Find a tutorial on using RigidBodies to do proper physics-aware movement, or just move all your code to Update() because right now you might have some frames where your object doesn't move and other frames where it moves twice the distance. This will happen because FixedUpdate() may get executed any number of times (including 0) in a single frame, depending on a setup. FixedUpdate runs firmly 50 times per second by default, while Update runs roughly 60 times per second (on mobile 30) by default. And lastly, in FixedUpdate never use Time.deltaTime, use Time.fixedDeltaTime:
Time.deltaTime is equal to roughly 1 / 60th of a second (1 frame duration)
Time.fixedDeltaTime is roughly 1 / 50th of a second (1 physics update duration)
FixedUpdate can be called multiple times per frame in succession. This is based on the physics settings for your project. You can edit this to add more or less accuracy to your physics.
Update is called only 1 time a frame.
So you want to avoid doing logic in the FixedUpdate. If you want to move a rigid body use MovePosition.
From the Unity docs: If Rigidbody interpolation is enabled on the Rigidbody, calling Rigidbody.MovePosition results in a smooth transition between the two positions in any intermediate frames rendered. This should be used if you want to continuously move a rigidbody in each FixedUpdate.
I want to instantiate a projectile and be able to rotate it as a child of a parent player object.
My player has a 2DRigidbody and box collider 2D, my projectiles also have a 2DRigidbody and box collider 2D, so when I shoot them from the player they bounce the player everywhere, but when I try to instantiate them elsewhere the player either jumps to that location or they appear away from the player, so I'd like to instantiate them as a child of the player.
My code for the Player
using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {
// Calls Variables
public Rigidbody2D lazer;
public float speed = 1.0f;
public float hitpoints = 100;
public float lazerlevel = 1;
Transform ParentPlayer;
// Initalizes variables
void Start () {
}
// Updates once per frame
void Update () {
var move = new Vector3(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"), 0);
transform.position += move * speed * Time.deltaTime;
if (Input.GetButtonUp("Fire1")) {
//Rigidbody2D instance = Instantiate(lazer, transform.position = new Vector3(0,-5,0), transform.rotation) as Rigidbody2D;
//Vector3 fwd = transform.TransformDirection(Vector3.down);
//instance.AddForce(fwd * 20 * lazerlevel);
GameObject objnewObject = (GameObject)Instantiate(lazer, new Vector3(0, 0, 0), transform.rotation);
objnewObject.transform.parent = ParentPlayer;
}
}
}
And my code for the lazer
using UnityEngine;
using System.Collections;
public class PlayerProjectileDoom : MonoBehaviour {
void ontriggerenter() {
Destroy(gameObject);
}
void Update () {
Destroy(gameObject, 2F);
}
}
You never assigned ParentPlayer in Player script. And you want to assign instantiated object as the child of Player. So the possible way to achieve this is to instantiate your object first, set it as child and then set the transformations to identity because after setting it as child its transformations will become relative to parent.
For example,
void Update () {
var move = new Vector3(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"), 0);
transform.position += move * speed * Time.deltaTime;
if (Input.GetButtonUp("Fire1")) {
GameObject objnewObject = Instantiate(lazer) as GameObject;
objnewObject.transform.parent = transform;
objnewObject.transform.localRotation = Quaternion.identity;
objnewObject.transform.localPosition = Vector3.zero;
}
}
Second thing is in your PlayerProjectileDoom script. You did implement OnTriggerEnter in wrong way. You should be careful when you are implementing these messages.
Third thing is you are calling Destroy in Update method, however it will work if you put it in Start. I'd recommend use Update at least as possible and absolutely not for these kind of events.
It should be like,
using UnityEngine;
using System.Collections;
public class PlayerProjectileDoom : MonoBehaviour {
void Start(){
Destroy(gameObject, 2F);
}
// For 3D colliders
void OnTriggerEnter(Collider coll) {
Destroy(gameObject);
}
// For 2D colliders
void OnTriggerEnter2D(Collider2D coll) {
Destroy(gameObject);
}
void Update () {
}
}
So you are using 2D colliders so you should go with 2D collider message and remove the 3D one.
An extra note: OnTriggerEnter or OnTriggerEnter2D will execute only iff you set colliders as Trigger. You can see this Trigger check in Inspector by selecting that gameobject having any collider. But if it is not set to Trigger then you should use OnCollisionEnter2D(Collision2D coll)