Projectile in Unity 2D - c#

I'm attempting to learn Unity (so please forgive my newbie-ness). I've set up my project as 2d, got a sprite moving about and I'm trying to get a projectile firing (I appreciate there are MANY SO q's about such, but I just can't get it to work, after trying many solutions). I'm a complete nub when it comes to physics!
Here's my very simple script:
using UnityEngine;
using System.Collections;
public class PlayerScript : MonoBehaviour {
public Transform mObject;
public Transform mProjectile;
public Vector2 mProjectileSpeed = new Vector2 (10f, 10f);
public Vector2 mSpeed = new Vector2(15, 15);
private Vector2 mMovement;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
float inputX = Input.GetAxis("X");
float inputY = Input.GetAxis("Y");
mMovement = new Vector2 (mSpeed.x * inputX, mSpeed.y * inputY);
if (Input.GetButton ("Fire1"))
Shoot ();
}
void Shoot(){
GameObject clone = (GameObject)Instantiate (mProjectile, rigidbody2D.transform.position, Quaternion.identity);
clone.rigidbody2D.velocity = (clone.transform.forward * 1000);
}
void FixedUpdate(){
rigidbody2D.velocity = mMovement;
}
}
And this is what it's doing:
No force is being added to the instantiated object and it shoots out both sides of my sprite, which I just don't understand at all.
I did find a solution on the Unity answers site that said to IgnoreCollider just in case the two box colliders were conflicting results, but it didn't make a difference.
I'm sure I'm doing something completely stupid, but how can I do this?
Many thanks!

Try using Addforce() method,
something like this :
gameObj.rigidbody2D.AddForce(Vector3.up * 10 * Time.deltaTime);
or
gameObj.rigidbody2D.AddForce(transform.forward * 100);
or
gameObj.rigidbody2D.AddForce(Vector3.up * 1000);
See which combination and what values matches your requirement and use accordingly. Hope it helps

As #maZZZu said, Instantiate your projectile sprites ahead of your character so that your character and projectiles may not collide.
Secondly, clone.rigidbody2D.velocity = (clone.transform.forward * 1000); part of your code will only allow the projectile to move in forward direction (x-axis in case to 2D and z-axis in 3D). Try using mMovement instead (if you want it to move in other directions as well). e.g. clone.rigidbody2D.velocity = (mMovement * 1000);

Related

Struggling in Unity 3d object Controls

I'm totally new to Unity and game development...I made a 2D object of the car that can move to 8 directions....each direction with the specific animation of the car's movement...Now, how do I make my car move in such a way that if it's moving straight LEFT it shouldn't go immediately straight to RIGHT when turning RIGHT, so I want it to make a proper round turn or a "U TURN" to move towards its opposite direction and obviously the same with UP and DOWN turns....can anyone please help me in at least one way I can fix this?
or the other way to ask this question would be if I'm moving my object to x = -1 direction then on turning to x = 1 it should first go through x = 0 and then x = 1 so that it looks like a turn.
this is the code for my CAR so far..
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CARmovement : MonoBehaviour
{
public float speed;
private Rigidbody2D myRigidbody;
private Vector3 change;
private Animator animator;
private Vector3 lastMoveDirection;
// Start is called before the first frame update
void Start()
{
animator = GetComponent<Animator>();
myRigidbody = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
change = Vector3.zero;
change.x = Input.GetAxis("Horizontal");
change.y = Input.GetAxis("Vertical");
UpdateAnimationAndMove();
}
void UpdateAnimationAndMove()
{
if (change != Vector3.zero)
{
MoveCar();
animator.SetFloat("moveX", change.x);
animator.SetFloat("moveY", change.y);
animator.SetBool("driving", true);
}
else
{
animator.SetBool("driving", false);
}
}
void MoveCar()
{
myRigidbody.MovePosition(transform.position + change * speed * Time.deltaTime);
}
}
I try an example of rotating a car. We add an object (here I add a car as an example), select the object (car) to create a C# Script script, double-click to open, we define two variables Speed_move, Speed_rot to control the movement speed and Rotation speed and assign values to them. We use Translate to control the forward and backward movement of the cube through the W and S buttons, forward with forward, and back with back; use Rotate to control the rotation of the object through the A and D buttons, up is the Y-axis rotation. The following is the code for the specific rotation.
if (Input.GetKey(KeyCode.W))
{
this.transform.Translate(Vector3.forward * Time.deltaTime * Speed_move);
}
if (Input.GetKey(KeyCode.S))
{
this.transform.Translate(Vector3.back * Time.deltaTime * Speed_move);
}
if (Input.GetKey(KeyCode.A))
{
this.transform.Rotate(Vector3.up * Time.deltaTime * -Speed_rot);
}
if (Input.GetKey(KeyCode.D))
{
this.transform.Rotate(Vector3.up * Time.deltaTime * Speed_rot);
}

Unity, how find my game object and move it

I'm totally newbie with Unity and C# and i try to do a 3D game.
I want to when i press "Qkey", the cube descends in height.
here is my code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ripcube : MonoBehaviour
{
// Start is called before the first frame update
bool isTeleported = false;
// Update is called once per frame
void Update()
{
if (Input.GetKey("a") && !isTeleported)
{
ripcube.transform.position = (-2, -2, -2) ;
}
}
}
And it gives me the error:
(19,13): error CS0120: An object reference is required for the non-static field, method, or property 'Component.transform'
I know than ripcube is my class, but what is my gameobject? i created my cube on the graphics interface..
Thanks for your help
You should go watch some basic videos on youtube on how unity gameobjects work but for now:
You can reference game objects from your code or find them as following:
public class ripcube: MonoBehaviour
{
GameObject myCubeObject;
float speed = 2f;
void Start()
{
myCubeObject = GameObject.Find("YourCubeNameInUnity");
}
void Update()
{
if(Input.GetKey(KeyCode.Q))
{
myCubeObject.transform.Translate(speed * Vector3.down * Time.deltaTime);
}
}
}
Thing you should notice here :
The GameObject is a Unity class that is the base for all the game objects in the scene,
you can find it by its name in the Hierarchy view.
After you find it you can access it in the Update() function and change its transform every frame.
Here I used Translate wich is an addition to the position every frame
you can also use myCubeObject.transform.position += speed * Vector3.down * Time.deltaTime
Be aware that im using a float speed variable that is the speed the cube will go in the desired direction (I used 2 for the value but it can be anything really).
The direction is specified by a vector (Vector3.down). You can change is as you please
Multiplying by Time.deltaTime makes the movement independant on FPS (Frames per second) wich is determined normally bt the machine the game is running on.
bro you can use
transform.position = new Vector3(-2, -2, -2);
instead of
transform.position = (-2, -2, -2) ;
and change
Input.GetKey("a")
to
Input.GetKey(KeyCode.Q)

transform.position not setting correct position in Unity?

I am having this problem that I don't know how to solve, I have a moving object that return to a position if a condition is verified, but it seems like it is working sometimes, but sometimes it is not ..
Here is my script :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MovingDes : MonoBehaviour {
private float speed = 5f;
Transform trn;
//-37.6914
//62.32123
// Use this for initialization
void Start() {
trn = GetComponent<Transform>();
}
// Update is called once per frame
void Update() {
transform.Translate(Vector3.back * (speed * Time.deltaTime));
if(transform.position.z <= -37.6914){
Vector3 newPosition = new Vector3(17.5f,125.7f,165.32123f);
trn.position = newPosition;
}
}
}
The problem is that I can see in my Unity editor that the position is different from what I have set, and I don't understand from Where those values came from, I did not write them for sure.
Any help would be much appreciated.
You are moving object with transform.Translate every frame, so immediately after setting up new position, your object is moved again. Notice that in your case trn, and transform, refers to the same Transform component.
Why don't you change your trn.position= to transform.position= I don't think you need GetComponent<> for transform component of the current gameObject. Or maybe related to relativeTo parameter of .Translate method.

How to make enemy circle player when in range?

I am working on a propably simple script. As I am new to coding and stuff, there is a high chance that my code looks horrible.
Okay, so here's the thing:
I have an enemy triggered, and only spawning when the player get's near a certain point. Then the Enemy has to follow the player, doesn't matter where he is, and keeping a certain range of 3 units.
To this point. Everything works fine.
Now, what doesn't seem to work is, that I need my enemy to "orbit" around my player, when he is in a certain range (3) and only then.
For now, it's orbiting right from the start...what did I miss??
Thats my code so far:
public Transform mTarget;
float mSpeed = 10.0f;
const float EPSILON = 3.0f;
public float speed;
void Start()
{
OrbitAround ();
}
void Update() {
transform.LookAt (mTarget.position);
if ((transform.position - mTarget.position).magnitude > EPSILON)
transform.Translate (0.0f, 0.0f, mSpeed * Time.deltaTime);
}
void OrbitAround() {
if(Vector3.Distance(transform.position, mTarget.transform.position) < 3) {
transform.RotateAround (mTarget.transform.position, Vector3.up, speed * Time.deltaTime);
}
}
Big Thanks in advance, if anyone can help me out.
Cheers,
As #Zibelas said, the Start function is only once.
The Unity documentation states:
Start is called on the frame when a script is enabled just before any of the Update methods is called the first time.
So try putting the call to OrbitAround() in the Update function and it should work
Well, didn't really fixed this problem exactly, but I found a way to work around it.
I just enabled the script to orbit around the target, when the enemy get close to it and disabled it, when the player goes away again.
void Update (){
if (Vector3.Distance (transform.position, mTarget.transform.position) < 15) {
script.enabled = true;
}
if(Vector2.Distance(transform.position, mTarget.transform.position) >15) {
script.enabled = false;
}
Still, thanks for the comments and information, guys.

How to attach the camera to a player object instantiated by HLAPI Network Manager?

In short, I have a very simple multiplayer game. It's the Roll A Ball game (Unity3D tutorial). So right now I have the players etc spawning perfectly and everyone is able to control their own balls perfectly fine.
But here's the problem: I've got a default Main Camera. Since it's only the local player itself that needs to see it, I figured there's no point in trying to spawn a seperate camera for each player on the server.
However, to make the camera follow the player, I need to attach it the player gameobject. Obviously I can't attach it to the player prefab as it's a clone the camera needs to follow. But since the player is being spawned by the Network Manager component, I have no idea on how to refer to this clone.
What I've tried myself:
public class CameraController : NetworkManager
{
public GameObject playerPrefab;
public Transform target;
private Vector3 offset;
public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)
{
GameObject player = (GameObject)Instantiate(playerPrefab, new Vector3(0, 0.5f, 0), Quaternion.identity);
target = player.transform;
NetworkServer.AddPlayerForConnection(conn, player, playerControllerId);
}
void Start()
{
offset = transform.position - target.position;
}
void LateUpdate()
{
transform.position = transform.position + offset;
}
}
But this resulted in:
Which I find extremely odd since as you can clearly see, there's no NetworkIdentity component on the NetworkManager object. I've been trying A LOT of things for the past 4 hours now and I just can't do it. So now I'm hoping you guys can help me out.
Edit: This is how the Network Manager normally spawns a player. As you can see, there's no code for it:
I had the same issue and figured out the followig solution. Seems like you already got a solution, but maybe it is interesting to share some possible ways for other people in the same situation.
This is a way to do it without a camera attached to the prefabs.
I'm using a NetworkManager to instantiate Player-prefabs. (Same as you)
I solved the problem of finding references to the clone objects by letting the clones tell the camera, who they are (or which transform belongs to them).
The Player has the following script:
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
public class PlayerController : NetworkBehaviour {
public override void OnStartLocalPlayer()
{
GetComponent<MeshRenderer>().material.color = Color.blue;
Camera.main.GetComponent<CameraFollow>().target=transform; //Fix camera on "me"
}
void Update ()
{
if (!isLocalPlayer)
{
return;
}
var x = Input.GetAxis("Horizontal") * Time.deltaTime * 150.0f;
var z = Input.GetAxis ("Vertical") * Time.deltaTime * 3.0f;
transform.Rotate (0, x, 0);
transform.Translate (0,0,z);
}
}
On my default main Camera (there is no camera attached to the player prefab, just the default camera) I put the following script on. It takes a target which I initialised with the prefab using the inspector.
using UnityEngine;
using System.Collections;
public class CameraFollow : MonoBehaviour {
public Transform target; //what to follow
public float smoothing = 5f; //camera speed
Vector3 offset;
void Start()
{
offset = transform.position - target.position;
}
void FixedUpdate()
{
Vector3 targetCamPos = target.position + offset;
transform.position = Vector3.Lerp (transform.position, targetCamPos,smoothing * Time.deltaTime);
}
}
After starting the game, each clone tells the camera who he is, so the target changes to the individual clients clone with this line from the Player's Script:
Camera.main.GetComponent<CameraFollow>().target=transform; //Fix camera on "me"
This way you don't need to create one camera per instance of player-prefabs (I'm not sure if this makes big differences in performance) and you don't have to deactivate all cameras which don't belong to your client.
If you host the game in the editor you can see that there is just 1 camera instead of one camera per connected client (like when you attach it to the prefab).
I think this is a good use of this method, you can use it to put things in it, which should be applied to the Local Player only.
public override void OnStartLocalPlayer()
{
}
I tried by starting the game in the editor and in a build and it seems to work well.
I would add a camera to the prefab and then write a player script like this:
using UnityEngine.Networking;
public class Player : NetworkBehaviour
{
public Camera camera;
void Awake()
{
if(!isLocalPlayer)
{
camera.enabled = false;
}
}
}
I've not really worked with networking but what if you do this after you spawn the local player
Camera.main.transfor.SetParent(the transform of the local player here);
As I understand the problem each separate instance of the game has a main camera.
Thanks to Rafiwui's point into the right direction, I've finally managed to get it working. All I had to do was adept his code a bit. The end result was:
public Camera camera;
void Awake()
{
camera.enabled = false;
}
public override void OnStartLocalPlayer()
{
camera.enabled = true;
}
Thanks A LOT to you all for helping me out! This has been quite a day for me.

Categories

Resources