C# Help with 2D project
Hello guys can any of you help me please? This is my first attempt at C# scripting and I'm having a bit of trouble with the script between the /* */. It should instantiate a cannon ball with a smoke effect, and according to my knowledge of JavaScript this script should work (if I'm converting it right). Also how can I stop the rotation on a key press?
using UnityEngine;
using System.Collections;
public class StartingPoint : MonoBehaviour {
public float rotSpeed = 80;
public GameObject cannon;
public float launchForce = 100;
//public GameObject fireEffect;
public GameObject spawn;
public GameObject bullet;
private GameObject reFire;
private GameObject spawnedObject;
private Rigidbody2D body;
//private float startTime;
void Start () {
//startTime = Time.time;
}
void Update () {
cannon.transform.localEulerAngles = new Vector3(0, 0,
Mathf.PingPong(Time.time * rotSpeed, 90));
if (Input.GetKeyDown(KeyCode.Space) == true) {
Debug.Log("Fire Gun");
/*reFire = Instantiate (fireEffect, spawn.transform.position,
spawn.transform.rotation);
spawnedObject = Instantiate (bullet, spawn.transform.position,
spawn.transform.rotation);
body = spawnedObject.GetComponent(Rigidbody2D);
body.AddForce (spawn.transform.position * launchForce, ForceMode2D.Impulse);*/
}
}
}
Any help would be great.
using UnityEngine;
using System.Collections;
public class StartingPoint : MonoBehaviour {
public float rotSpeed = 80;
public GameObject cannon;
public float launchForce = 100;
//public GameObject fireEffect;
public GameObject spawn;
public GameObject bullet;
private GameObject reFire;
private GameObject spawnedObject;
private Rigidbody2D body;
//private float startTime;
void Start () {
//startTime = Time.time;
}
void Update () {
cannon.transform.localEulerAngles = new Vector3(0, 0,
Mathf.PingPong(Time.time * rotSpeed, 90));
if (Input.GetKeyDown(KeyCode.Space) == true) {
Debug.Log("Fire Gun");
/*reFire = Instantiate (fireEffect, spawn.transform.position,
spawn.transform.rotation);
spawnedObject = Instantiate (bullet, spawn.transform.position,
spawn.transform.rotation);
body = spawnedObject.GetComponent(Rigidbody2D);
body.AddForce (spawn.transform.position * launchForce, ForceMode2D.Impulse);*/
}
}
}
Any help would be great.
Comments
C# is strongly typed.
Use:
body = spawnedObject.GetComponent<Rigidbody2D>();
The text between the angle brackets tells the GetComponent method what component type you're looking for.
You can also do spawnedObject.GetComponent(typeof(Rigidbody2D)) as Rigidbody2D; but that is ugly.
To stop rotation, goto your prefab with the Rigidbody2D component, and look in the "constraints" section. Tick the "Freeze Rotation" box. This can also be done through code.
Although sometimes you don't know if the component you're looking for is there. The (type) cast with throw an exception, so you can do this instead:
And the null check will be much faster than handling an exception.
That being said, I'm not sure of any reason to ever not use
Side note, notice that you don't need == true in your if statement since GetKeyDown already returns a bool.
So by adding == true what you're really saying is if (true == true) which is always redundant since it always equates to what GetKeyDown returned anyway.
using UnityEngine;
using System.Collections;
public class StartingPoint : MonoBehaviour {
public float rotSpeed = 80;
public GameObject cannon;
public float launchForce;
public GameObject spawn;
public GameObject bullet;
public Rigidbody cannonBody;
private GameObject spawnedObject;
private Rigidbody body;
private float tel;
//private float startTime;
private int launchUpgrade;
void Start () {
//startTime = Time.time;
tel = 0;
}
void Update () {
// This object rotates and I want it to stop when I press space.
// How can I tell the mathf.pingpong to rotate between 2 set rotations?
cannon.transform.localEulerAngles = new Vector3(0, 0,
Mathf.PingPong(Time.time * rotSpeed, 90));
if (Input.GetKeyDown(KeyCode.Space) && tel == 0) {
Debug.Log("Fire Gun");
spawnedObject = (GameObject)Instantiate (bullet, spawn.transform.position,
spawn.transform.rotation);
body = spawnedObject.GetComponent<Rigidbody>();
body.AddForce ( - spawn.transform.position * launchForce,
ForceMode.Impulse);
tel = 1;
//attempt at implamenting the freezeRotation.
cannonBody.freezeRotation = true;
}
}
}
It should be trivial to change the offset to a variable and set it to whatever you want. Alternatively, you can simply rotate the StartingPoint gameobject, provided that Cannon is a child of it in the hierarchy. Because you're using localEulerAngles it'll rotate relative to its parent transform and you'll be good to go.
Finally, the logic of making the cannon stop rotating isn't too complex: Just don't tell it to rotate if you don't want it to!
Now you can just set cannonRotating to false and the cannon will stop rotating completely. When and how you set cannonRotating is entirely up to you :) Messing with rotation freezing on a rigidbody is only really useful if that gameobject's movement is being controlled by the rigidbody, in your example you're setting rotation manually and bypassing the rigidbody completely.
while (launchUpgrade > 0){
cannonRotating = true;
cannon.transform.localEulerAngles = new Vector3(0, 0, - 90 +
Mathf.PingPong(Time.time * rotSpeed, 60));
}
Also has the benefit of reducing logical complexity.
This is very typical programmer "help" - pithy 1 liners that show off how the writer knows more than someone else, full of technically correct information with zero context for the person experiencing the problem :(
This is why we can't have nice things. But yes, you're 100% technically right, well done, etc.
@dislekcia, nice job man.