I am a beginner at unity and try to make a game by watching some tutorial. After finishing my game I wanted to add some more functionality which is dropping objects continuously from up to the plane. But after it dropped on the plane it rising up to a certain level and again dropped on the plane. I don't understand what to do.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class droper : MonoBehaviour
{
// Start is called before the first frame update
MeshRenderer renderer;
Rigidbody rigidbody;
Vector3 pos1;
Vector3 pos2;
Vector3 pos3;
[SerializeField]float timeToWait =2f;
[SerializeField]float speed =0.005f;
void Start()
{
renderer = GetComponent<MeshRenderer>();
rigidbody = GetComponent<Rigidbody>();
renderer.enabled= false;
rigidbody.useGravity= false;
pos1 = transform.position;
}
// Update is called once per frame
void Update()
{
if (Time.time > timeToWait)
{
renderer.enabled= true;
rigidbody.useGravity= true;
pos2 = transform.position;
Debug.Log(pos1);
pos3=new Vector3(transform.position.x,pos1.y,transform.position.z);
if (pos2.y < pos1.y)
{
transform.position=Vector3.MoveTowards(pos2,pos3,speed);
}
}
}
}
enter image description here
You can do this in 2 ways
You can use rigidbody.velocity along the axis you want to move, you may want to disable gravity depending on what you are trying to achieve
Transform.translate is also an option but it has buggy physics so you shouldn't really use it
Related
As you can see in the screenshoot I can't see prefabs in the game tab but only in the editor. I have made a simple function for shooting(not finished yet), it works fine, it spawns the prefabs but i can't see them in the game tab, I have already tried changing the Sorting Layer, move the camera, change Z position but nothing appen.
This is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerAttack : MonoBehaviour
{
[SerializeField]
float delayBetweenShots = 0.4f;
float timePassedSinceLast = 0f;
// Start is called before the first frame update
void Start()
{
timePassedSinceLast = delayBetweenShots;
}
// Update is called once per frame
void Update()
{
Aiming();
Shooting();
}
void Aiming()
{
var objectPos = Camera.main.WorldToScreenPoint(transform.position);
var dir = Input.mousePosition - objectPos;
transform.rotation = Quaternion.Euler(new Vector3(0,0,Mathf.Atan2(-dir.x, dir.y) * Mathf.Rad2Deg));
}
void Shooting()
{
if(Input.GetMouseButton(0) && timePassedSinceLast >= delayBetweenShots)
{
GameObject bullet = (GameObject)Instantiate(Resources.Load("bullet"), transform.position, transform.rotation);
timePassedSinceLast = 0f;
}
else
{
timePassedSinceLast += Time.deltaTime;
}
}
}
The prefabs get instantiated correctly. As others suggested as well, the best way to find "lost" objects in your game is to shoot some stuff, pause the game, go into scene view, turn on 3D mode and double click one of the prefabs in the hierarchy. The camera will take you straight to your object.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float speed;
public float jumpForce;
private float moveInput;
private Rigidbody2D rb;
private bool facingRight = true;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
}
void FixedUpdate()
{
moveInput = Input.GetAxis("Horizontal");
rb.velocity = new Vector2(moveInput * speed, rb.velocity.y);
if(facingRight == false && moveInput > 0)
{
Flip();
}
else if(facingRight == true && moveInput < 0)
{
Flip();
}
}
void Flip()
{
facingRight = !facingRight;
Vector3 Scaler = transform.localScale;
Scaler.x *= -1;
transform.localScale = Scaler;
}
}
I'm made a c# 2D player controller script to use in unity, but when I hit play, my player won't flip and face a different direction when he moves a different direction. Can anyone spot what's wrong in my script?
Nevermind. Was just a dumb bug. I put an outdated AND updated script component into my player. Yes I know I'm stupid.
Unity seems a good choice to developp your game but due to the simplicity of your game, i think it will be easier to create it using Android Studio, it is more easier to handler Character Sprite and Animation. All depend of what kind of game you want to create.
"""For instances guys, i create a simple SkaterBoard game using simple gravity physics with Android Studio, I would really appreciate if you could left a review on it."""
(Android Link) Skater Soldier Game: https://play.google.com/store/apps/details?id=com.fight.exempleclass
Always make sure you double check settings, values, and where you attached scripts : )
I've heard a couple people advise against flipping via scale and instead prefer :
transform.Rotate(0f, 180f, 0f);
Or depending on the gameplay / utility needed using SpriteRenderer.flipX
In case you'd like alternatives.
I have a rectangle player sprite with a Box Collider 2D and a Rigidbody2D attached. I also have a script for point-and-click movement attached to the player object (i.e. player moves to mouse click position). However as soon as the player character hits a collider, it starts to jitter rather than just fully stop. I don't know a lot about Unity physics other than what I've picked up in a few tutorials, so I'll include as much relevant information as I can.
The Rigidbody 2D component has all forces set to 0, except for mass being 0.0001. The body type is dynamic, and collision detection is set to continuous. My movement script looks like this, got it straight from a tutorial:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControls : MonoBehaviour
{
public float speed = 1;
private Vector3 target;
void Start()
{
target = transform.position;
}
void Update()
{
if (Input.GetMouseButtonDown(0)) {
target = Camera.main.ScreenToWorldPoint(Input.mousePosition);
target.z = transform.position.z;
}
transform.position = Vector3.MoveTowards(transform.position, target, speed * Time.deltaTime);
}
}
Is there an easier way to implement smooth point-and-click movement?
I'm new to Unity and to C#. I was trying to code a 2D platformer movement script, but for some reasons the code I'm creating doesn't work.
The script is referred to a circle. I've added "Rigidbody2D" and "Circle Collider 2D".
I've tried to use this script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour
{
public Rigidbody2D rb;
public void FixedUpdate()
{
if (Input.GetKey(KeyCode.RightArrow))
{
rb.AddForce(10, 0, 0);
}
}
}
The code should give an hit to the circle to make it move right, but Visual Studio says that "rb.AddForce" is an error. Can you help me, please?
Are you sure you have actually referenced the rigidbody? Did you drag the rigidbody in the editor? If you have not, you could also say the following (if the script is attached to object that holds the rigidbody you would like to move):
private Rigidbody2D rb;
private void Start()
{
rb = GetComponent<Rigidbody2D>();
}
1)Make sure your Rigidbody component is NOT set to Kinematic.
2)Depending on the mass and linear drag of the rigidbody, you would need to change the force you apply to it accordingly. The code may be working but you would not see the body moving if you do not apply enough force.
3)Addforce() expects a Vector as an argument. This is your problem.
public float thrust; //set in editor, this is how strong you will be pushing the object
private Rigidbody2D rb;
private void Start()
{
rb = GetComponent<Rigidbody2D>();
}
private void FixedUpdate()
{
if (Input.GetKey(KeyCode.RightArrow))
{
rb.AddForce(transform.right * thrust); //this will move your RB to the right while you hold the right arrow
}
}
4) Set a linear drag of your rigidbody so that it can actually stop after applying the force to it. In order to make it work, set the mass and linear drag both to 1 for example and then just experiment with the thrust variable, it will eventually start moving. After that you can reduce/increase the linear drag and the thrust until you achieve the desired effect.
BONUS
If you wish to use a Vector3D the way you have tried in your code, you could do the following and it will work too:
private void FixedUpdate()
{
if (Input.GetKey(KeyCode.RightArrow))
{
rb.AddForce(new Vector3(10, 0, 0)); //this will move your RB to the right while you hold the right arrow
}
}
Because of Rigidbody2D implementation it takes Vector2 in constructor as an argument instead of simple Rigidbody which can take Vector3 and Vector2 as Vector3. Consider Vector3 v3 = new Vector2(10, 0); and
Vector2 v2 = new Vector3(10, 0, 0);
Try this
rb.AddForce(new Vector2(10, 0));
or
rb.AddForce(new Vector3(10, 0, 0));
You need to add ForceMode2D.Impulse for it to work:
using UnityEngine;
public class TestControl : MonoBehaviour
{
public Rigidbody2D rb2d;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.RightArrow))
{
rb2d.AddForce(new Vector2(5, 0 ), ForceMode2D.Impulse);
Debug.Log("RightArrow was Pressed");
}
}
}
You can find more info in here: https://www.studytonight.com/game-development-in-2D/right-way-to-move
I'm writing a script in C# in Unity that essentially functions as a switch to turn gravity on or off for a 2D Rigidbody. When the game starts, gravity should be 0 for the Rigidbody. Then when the user taps the space bar, gravity is supposed to increase to 3 (which is does). Then, however, when the player collides with a gameObject labeled 'InvisGoal', the player should teleport to another location and then gravity should be 0 again. However, the player always falls after coming in contact with InvisGoal and teleporting and I can't figure out why. This is my first project in C# so sorry for any obvious errors.. The script is here:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BallLaunch : MonoBehaviour {
private Rigidbody2D myRigidBody;
public GameObject Ball;
// Use this for initialization
void Start ()
{
myRigidBody = GetComponent<Rigidbody2D> ();
GetComponent<Rigidbody2D>().gravityScale = 0f;
}
// Update is called once per frame
void Update ()
{
if (Input.GetButtonDown ("Jump"))
{
GetComponent<Rigidbody2D> ().gravityScale = 3f;
}
}
void OnTriggerEnter2D(Collider2D other){
if (other.tag == "InvisGoal")
{
Ball.gameObject.GetComponent<Rigidbody2D>().gravityScale = 0f;
transform.position = new Vector3 (0.61f, 1.18f, 0f);
return;
}
}
}
Ball.gameObject.GetComponent<Rigidbody2D>().gravityScale = 0f;
This is likely what is causing the problem.
It sounds like the RigidBody2D you are referencing to in this line is not the same as the one you retrieved beforehand with GetComponent().
GetComponent returns the component of the GameObject you call it from. Therefore in the code I mentioned above,
Ball.gameObject.GetComponent<RigidBody2D>()
and
GetComponent<RigidBody2D>()
would give you an two different RigidBody2D component if the field Ball does not refer to the same GameObject your BallLaunch script is attached to.
[
Supposing BallLaunch script is attached to the Ball you want to set the gravity of (As picture above)
Simply change:
Ball.gameObject.GetComponent<Rigidbody2D>().gravityScale = 0f;
To
GetComponent<Rigidbody2D>().gravityScale = 0f;
Also, since you already referenced your RigidBody2D in your Start method to the field myRigidBody, you can replace all subsequent GetComponent with myRigidBody.
GetComponent<Rigidbody2D>().gravityScale = 0f;
To
myRigidBody.gravityScale = 0f;