Issue with moving object along dynamically defined line - c#

I'm an absolute programming beginner. I'm working on a tiny game prototype just for fun.
You are dragging a character. When you drag the character, the char stays still and you see a targeting line, pointing the opposite direction. When you release the mouse button, the character should move along the targeting line until he hits something.
Everything pretty much works. But there is a slight offset. The character is moving a bit off the targeting line. I feel there is something wrong in the raycast part of the code (in the Dragging() method).
Here is my code:
using UnityEngine;
using System.Collections;
public class PlayerControllerTest : MonoBehaviour {
Rigidbody2D rig;
int dragging;
Vector3 mousePosition;
bool wasMoving;
LineRenderer lineRenderer;
void Start () {
lineRenderer = GetComponent<LineRenderer> ();
rig = GetComponent<Rigidbody2D> ();
}
void Update () {
if (dragging == 1) {
Dragging ();
}
if (dragging == 2) {
float distanceMouseToPlayer = Vector3.Distance (transform.position,mousePosition);
rig.velocity = (-transform.InverseTransformPoint (mousePosition))/distanceMouseToPlayer * 3;
}
}
void OnMouseDown()
{
dragging = 1;
}
void Dragging()
{
mousePosition = Camera.main.ScreenToWorldPoint (Input.mousePosition);
mousePosition.z = 0f;
var layerMask = 1 << 8;
layerMask = ~layerMask;
RaycastHit2D hit = Physics2D.Raycast (mousePosition,transform.position- mousePosition,Mathf.Infinity,layerMask);
lineRenderer.enabled = true;
lineRenderer.SetPosition (0, transform.position);
lineRenderer.SetPosition (1, hit.point);
}
void OnMouseUp()
{
dragging = 2;
lineRenderer.enabled = false;
}
}

Related

EnemyAI script not moving the Enemy

I am making my first foray into AI, specifically AI that will follow the player.
I am using the A* Path finding project scripts, but used the Brackeys tutorial for the code
https://www.youtube.com/watch?v=jvtFUfJ6CP8
Source in case needed.
Here's the code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Pathfinding;
public class EnemyAI : MonoBehaviour
{
public Transform Target;
public float speed = 200f;
public float NextWayPointDistance = 3f;
Path path;
int currentWaypoint = 0;
bool ReachedEndOfpath = false;
Seeker seeker;
Rigidbody2D rb;
public Transform EnemyGraphics;
// Start is called before the first frame update
void Start()
{
seeker = GetComponent<Seeker>();
rb = GetComponent<Rigidbody2D>();
InvokeRepeating("UpdatePath", 0f, 1f);
}
void UpdatePath()
{
if (seeker.IsDone())
seeker.StartPath(rb.position, Target.position, OnPathComplete);
}
void OnPathComplete(Path p)
{
if (!p.error)
{
path = p;
currentWaypoint = 0;
}
}
// Update is called once per frame
void fixedUpdate()
{
if(path == null)
return;
if(currentWaypoint >= path.vectorPath.Count)
{
ReachedEndOfpath = true;
return;
}
else
{
ReachedEndOfpath = false;
}
Vector2 Direction = ((Vector2)path.vectorPath[currentWaypoint] - rb.position).normalized;
Vector2 Force = Direction * speed * Time.fixedDeltaTime;
rb.AddForce(Force);
float distance = Vector2.Distance(rb.position, path.vectorPath[currentWaypoint]);
if(distance < NextWayPointDistance)
{
currentWaypoint++;
}
if(rb.velocity.x >= 0.01f)
{
EnemyGraphics.localScale = new Vector3(-1f, 1f, 1f);
}else if(rb.velocity.x <= 0.01f)
{
EnemyGraphics.localScale = new Vector3(1f, 1f, 1f);
}
}
}
How I tried to fix the issue:
I thought it could've been a problem with the speed so I increased it to 10000000, and still nothing
Next I thought it was a problem with the Rigidbody2d so I check there, found the gravity scale was set at 0, so I increased it to 1. It made my enemy fall to the ground but still no movement.
I thought it could've been a problem with the mass and drag, so I set Linear drag and Angular drag to 0, and also set mass to 1. Still nothing.
I set the body type to kinematic, pressed run, nothing. Set the body type to static, pressed run, nothing. Set the body type to Dynamic, pressed run, still nothing.
I tried to make a new target for the enemy to follow, dragged the empty game object i nto the target, pressed run and still didn't move.
I am at a loss on how to fix this.
Please help?
Looks like maybe a typo? You have:
// Update is called once per frame
void fixedUpdate()
{
but the method is called FixedUpdate(), with a big F in front. You have fixedUpdate, which is NOT the same.

How to respawn a paddle and ball in breakout - Unity 3D C#

I'm making a breakout game in 3D and it's my first time making a game and using Unity so I'm a bit clueless. I've got to the point where my game works fine up until the ball goes off the screen and into the "dead zone".
Can someone advise how to respawn the paddle and ball together and carry on with the game?
I've included my ball and paddle scripts below, I have a script for the bricks as well but not sure that was relevant. I also made a prefab of the ball and paddle together but no idea what to do with it.
Thanks to anyone who can help :)
Code for my ball
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BallScript : MonoBehaviour
{
public Rigidbody rbody;
public float MinVertMovement = 0.1f;
public float MinSpeed = 10f;
public float MaxSpeed = 10f;
private bool hasBeenLaunched = false;
void Start()
{
}
private float minVelocity = 10f;
private Vector3 lastFrameVelocity;
void FixedUpdate()
{
if (hasBeenLaunched == false)
{
if (Input.GetKey(KeyCode.Space))
{
Launch();
}
}
if (hasBeenLaunched)
{
Vector3 direction = rbody.velocity;
direction = direction.normalized;
float speed = direction.magnitude;
if (direction.y>-MinVertMovement && direction.y <MinVertMovement)
{
direction.y = direction.y < 0 ? -MinVertMovement : MinVertMovement;
direction.x = direction.x < 0 ? -1 + MinVertMovement : 1 - MinVertMovement;
rbody.velocity = direction * MinSpeed;
}
if (speed<MinSpeed || speed>MaxSpeed)
{
speed = Mathf.Clamp(speed, MinSpeed, MaxSpeed);
rbody.velocity = direction*speed;
}
}
lastFrameVelocity = rbody.velocity;
}
void OnCollisionEnter(Collision collision)
{
Bounce(collision.contacts[0].normal);
}
private void Bounce(Vector3 collisionNormal)
{
var speed = lastFrameVelocity.magnitude;
var direction = Vector3.Reflect(lastFrameVelocity.normalized, collisionNormal);
Debug.Log("Out Direction: " + direction);
rbody.velocity = direction * Mathf.Max(speed, minVelocity);
}
public void Launch()
{
rbody = GetComponent<Rigidbody>();
Vector3 randomDirection = new Vector3(-5f, 10f, 0);
randomDirection = randomDirection.normalized * MinSpeed;
rbody.velocity = randomDirection;
transform.parent = null;
hasBeenLaunched = true;
}
}
Code for my paddle
public class PaddleScript : MonoBehaviour
{
private float moveSpeed = 15f;
void Start()
{
}
void Update()
{
if (Input.GetKey(KeyCode.RightArrow) && transform.position.x<9.5)
transform.Translate(moveSpeed *Input.GetAxis("Horizontal")*Time.deltaTime, 0f, 0f);
if (Input.GetKey(KeyCode.LeftArrow) && transform.position.x>-7.5)
transform.Translate(moveSpeed *Input.GetAxis("Horizontal")*Time.deltaTime, 0f, 0f);
}
}
The simplest thing you can do to check wether the ball goes off screen is to place a trigger immediately off the perimeter of the camera, and add an OnTriggerEnter2D method to your ball.
/* Inside the ball script */
private void OnTriggerEnter() { // Use the 2D version if you're using 2D colliders
/* Respawning stuff */
}
Since you may want a bunch of different things to happen when that method triggers, you may want to use a Unity Event, which is not the king of performance but it probabily doesn't matter for a game like breakout.
using UnityEngine.Events;
public class BallScript : MonoBehaviour
{
public UnityEvent onBallOut;
/* ... */
private void OnTriggerEnter() {
onBallOut.Invoke();
}
}
You then probabily want a Respawn() method (not Reset() because that's a default MonoBehaviour call) which places the ball back to its original position, which you can store in a field as soon as the scene loads:
private Vector3 defaultPosition;
private void Start() {
defaultPosition = transform.position;
}
PS: If you aren't using the Start() method in your paddle script then remove it, cause it will be called by Unity even if empty.

How do i set the velocity of a sprite to the opposite direction of the mouse pointer at a certain speed?

/*I am making a 2d game in Unity that works similarly to billiards, but with other aspects. When the player holds down button 0, a line drags away from the ball to show the direction and speed the ball will be hit off in. I don't know how to set that velocity or how to add a force like that.
I've tried setting the velocity directly, then adding fake frictions, but that didn't work too well. I also tried adding a force to the ball, and also making an empty game object that follows the pointer with a point effecter to repel the ball. But I cant seem to get anything to work.
--Also I apologize for the messy code, i'm still kinda new to this
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LineDrawer : MonoBehaviour
{
public Transform tr; //this is the transform and rigid body 2d of the
ball
public Rigidbody2D rb;
public LineRenderer line; // the line rendered is on the ball
public float hitForce = 10;
// Start is called before the first frame update
void Start()
{
line = GetComponent<LineRenderer>();
line.SetColors(Color.black, Color.white);
}
// Update is called once per frame
void FixedUpdate()
{
line.SetPosition(0, tr.position - new Vector3(0, 0, 0));
if (Input.GetMouseButton(0)&&PlayerPrefs.GetInt("Moving")==0)
{
line.SetWidth(.25f, .25f);
line.SetPosition(1, Camera.main.ScreenToWorldPoint(Input.mousePosition));
float len = Vector2.Distance(line.GetPosition(0), line.GetPosition(1)); //this is for determining the power of the hit
}
else
{
line.SetWidth(0, 0); //make the line invisible
}
if (Input.GetMouseButtonUp(0) && (PlayerPrefs.GetInt("Moving")==0))
{
Vector2.Distance(Input.mousePosition, tr.position)*100;
Debug.Log("Up");
rb.velocity = //this is what i cant work out
PlayerPrefs.SetInt("Moving", 1);
}
}
}
//5 lines from the bottom is where i'm setting the velocity.
Just rewrite your script to the following:
using UnityEngine;
public class Ball : MonoBehaviour
{
private LineRenderer line;
private Rigidbody2D rb;
void Start()
{
line = GetComponent<LineRenderer>();
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
line.SetPosition(0, transform.position);
if (Input.GetMouseButton(0))
{
line.startWidth = .05f;
line.endWidth = .05f;
line.SetPosition(1, Camera.main.ScreenToWorldPoint(Input.mousePosition));
}
else
{
line.startWidth = 0;
line.endWidth = 0;
}
if (Input.GetMouseButtonUp(0))
{
Vector2 direction = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
direction.Normalize();
rb.AddForce(direction * 3f, ForceMode2D.Impulse);
}
}
}

Any way of moving my player other then the controller script teleports

I'm trying to make a spring wall in my 2d platformer. However every way I've tried to move my character (addforce, transform.translate and even tried using the bouncy naterial) teleports my character rather then moving it. This doesn't happen with my controller script. I suspect something in my script is causing this interaction but I'm not sure exactly what. Here is my controller script. Any suggestions would be greatly appreciated :))
using UnityEngine;
using System.Collections;
public class controller : MonoBehaviour
{
//how fast he can go
public float topSpeed = 15f;
bool facingRight = true;
//what direction character is facing
bool grounded = false;
//check if the character is grounded
public Transform groundCheck;
//the transform is used to see if character has touched the ground yet
float groundRadius = 0.2f;
//creates a ground radius for the transform circle for ground detection
GameObject Player, Player2;
int characterselect;
//I'm pretty sure this stuff ^^ is unnessecary and is from when I had the character switch in this script but dont want to remove just in case
public float jumpForce = 700f;
//the characters jumpforce
public GameObject jumpParticles;
public LayerMask whatIsGround;
//what layer is the ground
void Start()
{
characterselect = 1;
Player = GameObject.Find("Player");
Player2 = GameObject.Find("Player2");
//loads game objects as variables I'm pretty sure this stuff ^^^^ is unnessecary and is from when I had the character switch in this script but dont want to remove just in case
}
void FixedUpdate()
{
//has the transform hit the ground yet returns a true or false value
grounded = Physics2D.OverlapCircle(groundCheck.position, groundRadius, whatIsGround);
// get direction
float move = Input.GetAxis("Horizontal");
//add velocity to the move direction times by the speed
GetComponent<Rigidbody2D>().velocity = new Vector2(move * topSpeed, GetComponent<Rigidbody2D>().velocity.y);
if (move > 0 && !facingRight) //if facing not right then use the flip function
flip();
else if (move < 0 && facingRight)
flip();
//the whole flip turned out not to be nesseary as my sprites were symetric
}
void Update()
{
//if the character is in fact touching the ground then when space is pressed the function will run
if(grounded&& Input.GetKeyDown(KeyCode.Space))
{
//adds the jump force to the rigidbody attached to the character
GetComponent<Rigidbody2D>().AddForce(new Vector2(0, jumpForce));
//Instantiate(jumpParticles, transform.position, transform.rotation);
//Destroy(jumpParticles, 3f);
}
{
//this was code I was working on for character switching but couldn't get it to work properly. I didn't delete it because it took me ages to do and was recycled in the characterswitch script
// if (Input.GetKeyDown(KeyCode.E))
// {
// if (characterselect==1)
// {
// characterselect = 2;
// }
// else if (characterselect==2)
// {
// characterselect = 1;
// }
// }
// if (characterselect==1)
// {
// Player.SetActive(true);
// Player2.SetActive(false);
// }
// else if (characterselect==2)
// {
// Player.SetActive(false);
// Player2.SetActive(true);
// }
}
if (Input.GetKeyDown(KeyCode.LeftShift))
{
topSpeed = topSpeed * 2;
}
else if (Input.GetKeyUp(KeyCode.LeftShift))
{
topSpeed = 15;
}
}
void flip()
{
//for when facing the other direction
facingRight = ! facingRight;
//load the local scale
Vector3 theScale = transform.localScale;
//flip character on the x axis
theScale.x *= -1;
//and then apply it to the local scale
transform.localScale = theScale;
}
Edit
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class boost : MonoBehaviour {
private Rigidbody2D rb2d;
// Use this for initialization
void OnCollisionEnter2D(Collision2D other){
if (other.gameObject.tag == "booster") {
Vector2 tempvect = new Vector2 (2, 0);
rb2d.MovePosition ((Vector2)transform.position + tempvect);
}
}
void Start () {
rb2d = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update () {
}
}
This is the code that I think should make it work the error comes at
rb2d.MovePosition ((Vector2)transform.position + tempvect);

How Do I Shoot a Projectile into the Direction the Player is Facing?

I am creating a 2D side-scroller video game in Unity using c#. I have created the script that makes the player face the direction that the arrow key that was pressed was pointing to (when the right arrow is pressed, the player faces right. When the left arrow is pressed, the player faces left).
However, I cannot figure out how to make the harpoon that the player shoots point in the direction the player is facing. I have found many questions on Stack Overflow asking questions like this, but none of their answers worked for me.
Can anyone please tell me how to make the harpoon the player shoots face the direction the player is facing? Thanks in advance!
Here is my code that I use-
PLAYER SCRIPT
using UnityEngine;
using System.Collections;
public class playerMove : MonoBehaviour {
// All Variables
public float speed = 10;
private Rigidbody2D rigidBody2D;
private GameObject harpoon_00001;
private bool facingRight = true;
void Awake () {
rigidBody2D = GetComponent<Rigidbody2D>();
harpoon_00001 = GameObject.Find("harpoon_00001");
}
void Update () {
if (Input.GetKeyDown(KeyCode.LeftArrow) && !facingRight) {
Flip();
}
if (Input.GetKeyDown(KeyCode.RightArrow) && facingRight) {
Flip();
}
}
void Flip () {
facingRight = !facingRight;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
void FixedUpdate () {
float xMove = Input.GetAxis("Horizontal");
float yMove = Input.GetAxis("Vertical");
float xSpeed = xMove * speed;
float ySpeed = yMove * speed;
Vector2 newVelocity = new Vector2(xSpeed, ySpeed);
rigidBody2D.velocity = newVelocity;
if (Input.GetKeyDown("space")) {
GetComponent<AudioSource>().Play();
Instantiate(harpoon_00001,transform.position,transform.rotation);
}
}
}
HARPOON SCRIPT
using UnityEngine;
using System.Collections;
public class harpoonScript : MonoBehaviour {
// Public variable
public int speed = 6;
private Rigidbody2D r2d;
// Function called once when the bullet is created
void Start () {
// Get the rigidbody component
r2d = GetComponent<Rigidbody2D>();
// Make the bullet move upward
float ySpeed = 0;
float xSpeed = -8;
Vector2 newVelocity = new Vector2(xSpeed, ySpeed);
r2d.velocity = newVelocity;
}
void Update () {
if (Input.GetKeyDown(KeyCode.LeftArrow)) {
float xSpeed = -8;
}
if (Input.GetKeyDown(KeyCode.RightArrow)) {
float xSpeed = 8;
}
}
void OnTriggerEnter2D(Collider2D other) //hero hits side of enemy
{
Destroy(other.gameObject.GetComponent<Collider2D>()); //Remove collider to avoid audio replaying
other.gameObject.GetComponent<Renderer>().enabled = false; //Make object invisible
Destroy(other.gameObject, 0.626f); //Destroy object when audio is done playing, destroying it before will cause the audio to stop
}
}
You already defining a variable facingRight to know the direction of the the player. You can use that knowledge to control the harpoon.
For example:
// this line creates a new object, which has harpoonScript attached to it.
// In unity editor, you drag and drop this prefab(harpoon_00001) into right place.
// transform.position is used for the starting point of the fire. You can also add +-some_vector3 for better placement
// Quaternion.identity means no rotation.
harpoonScript harpoon = Instantiate(harpoon_00001,transform.position, Quaternion.identity) as harpoonScript;
// Assuming harpoon prefab already facing to right
if (!facingRight) {
// Maybe, not required
harpoon.transform.eulerAngles = new Vector3(0f, 0f, 180f); // Face backward
Vector3 theScale = harpoon.transform.localScale;
theScale.y *= -1;
harpoon.transform.localScale = theScale; // Flip on y axis
}

Categories