Mouse trail is teleporting when i click - c#

im trying to make a mouse trail. So when you hold the mouse button down, it starts the trail and you can move around and then when you release, it dissapers. Im using the trail renderer for this.
Im tryna to replica the blade thats seen in stuff like fruit ninja. So i have an empty game object called blade with a kinematic rigidbody 2d and my blade script.
I then have a trail which is a prefab that i drag into the blade script. Here is the blade script:
bool isCutting = false;
Rigidbody2D rb;
Camera cam;
public GameObject trail;
GameObject currentTrail;
private void Start()
{
rb = GetComponent<Rigidbody2D>();
cam = Camera.main;
}
void Update ()
{
if (Input.GetMouseButtonDown(0))
{
isCutting = true;
currentTrail = Instantiate(trail, transform);
} else if (Input.GetMouseButtonUp(0))
{
isCutting = false;
currentTrail.transform.SetParent(null);
}
if (isCutting)
{
rb.position = cam.ScreenToWorldPoint(Input.mousePosition);
Destroy(currentTrail, 2f);
}
}
The only problem is, when i hold my mouse down, the blade insanely teleports to my mouse position with the trail renderer.
So i think the default blade position is in the middle of the camera, if i drag and hold at the top, u can see the beginning of a blade is a straight line trail from the middle to the top and i want the trail to start where i click.
I hope that makes sense. Thanks

Try changing the last section of the Update() method to:
if (isCutting)
{
currentTrail.transform.position = rb.position = cam.ScreenToWorldPoint(Input.mousePosition);
Destroy(currentTrail, 2f);
}

Related

Collider2d.bounds.Intersects not detecting intersection

I'm making a top-down game where you drive a car and shoot targets at the same time. I have a script that makes a sprite of a crosshair follows the mouse cursor and I want to have it set up so that when the player presses the mouse button (the mouse button isn't in the code now) and the crosshair sprite is overlapping an enemy sprite, the enemy dies. I was following this documentation on Bounds.Intersects. Here's my code:
public class shootingScript : MonoBehaviour
{
public GameObject target, enemy;
CircleCollider2D targetCollider;
CapsuleCollider2D enemyCollider;
// Start is called before the first frame update
void Start()
{
//Check that the first GameObject exists in the Inspector and fetch the Collider
if (target != null)
{
print("targ not null");
targetCollider = target.GetComponent<CircleCollider2D>();
}
//Check that the second GameObject exists in the Inspector and fetch the Collider
if (enemy != null)
{
print("enemy not null");
enemyCollider = enemy.GetComponent<CapsuleCollider2D>();
}
}
// Update is called once per frame
void Update()
{
if (targetCollider.bounds.Intersects(enemyCollider.bounds))
{
print("hit");
Destroy(enemy);
}
}
}
In-game "targ not null" and "enemy not null" prints but when I move my cursor and the crosshair goes over the enemy "hit" is not printed and the enemy is not destroyed. I have a CircleCollider2D on the crosshair and a CapsuleCollider2D on the enemy. The script is on an empty game object. I also tried sprite.bounds but that resulted in the enemy getting killed as soon as I run the game.
EDIT:
Here's the code that keeps the crosshair sprite on the cursor. I copied it from somewhere. I set moveSpeed to 99999 since I want the crosshair sprite to be exactly where the mouse is.
public class mouseReticle : MonoBehaviour
{
private Vector3 mousePosition;
public float moveSpeed = 0.1f;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
mousePosition = Input.mousePosition;
mousePosition = Camera.main.ScreenToWorldPoint(mousePosition);
transform.position = Vector2.Lerp(transform.position, mousePosition, moveSpeed);
}
}
The target sprite and enemy sprite were at different depths (z).

Unity - Affect only clicked GameObject

I am new to unity, and I tried to create a prefab for a tile in a game. So whenever a user clicks the tile it should change its sprite. The problem is that all the copies (instances) in my game are changing their sprite.
This is what I tried:
void Update()
{
if (Input.GetMouseButtonDown(0))
{
GameObject gameObject = this.gameObject;
SpriteRenderer renderer = gameObject.GetComponent<SpriteRenderer>();
Sprite sprite = Resources.Load<Sprite>("Sprites/red");
renderer.sprite = sprite;
}
}
What am I doing wrong? Thanks in advance
You are detecting if the mouse button is pressed, not if it's pressed over the given tile.
There are several ways to do it, but I would say the standard way is to:
Attach a Collider to the GameObject
Implement OnMouseDown
void OnMouseDown()
{
GameObject gameObject = this.gameObject;
SpriteRenderer renderer = gameObject.GetComponent<SpriteRenderer>();
Sprite sprite = Resources.Load<Sprite>("Sprites/red");
renderer.sprite = sprite;
}
Like akin said you are changing all sprites on a mouse click, you can raycast to your objects and check if they are hit then change it
Run this part on a script attached to your player or camera
void FixedUpdate()
{
RaycastHit hit;
if (Physics.Raycast(transform.position, -Vector3.up, out hit, 100.0f)) {
if (hit.transform.gameObject.GetComponent<yourscript>()) {
hit.transform.gameObject.GetComponent<yourscript>().ChangeSprite();
}
}
}
attach to tile game objects
public class yourscript : MonoBehaviour
{
public void ChangeSprite() {
SpriteRenderer renderer = gameObject.GetComponent<SpriteRenderer>();
Sprite sprite = Resources.Load<Sprite>("Sprites/red");
renderer.sprite = sprite;
}
}

Following instruction for drag and drop 3d object unity but not working

Hi so i have followed every instruction from youtube videos (https://m.youtube.com/watch?v=NMt6Ibxa_XQ) but in the game mode i still cant drag and drop my cube, the cube just stay still when i click and drag it. This problem really gave me a headache i’m pretty sure i have followed every detail from the video and repeat it over and over, thank’s for your time and help i really appreciate and need it, thank youi
in order for your cube to take the OnMouseDown() event you need to add a collider and rigidbody. click the cube, go to the properties on the right and click
add component - physics - cube collider
then do the same, for the rigid body
add component - physics - rigid body.
dont forget to set the rigidbody to kinematic, or set the gravity scale to 0 if you dont want it to fall out of the scene
use this script in order to drad and drop 3D Objects :
using UnityEngine;
using System.Collections;
public class DragAndDrop : MonoBehaviour
{
private bool _mouseState;
private GameObject target;
public Vector3 screenSpace;
public Vector3 offset;
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
// Debug.Log(_mouseState);
if (Input.GetMouseButtonDown (0)) {
RaycastHit hitInfo;
target = GetClickedObject (out hitInfo);
if (target != null) {
_mouseState = true;
screenSpace = Camera.main.WorldToScreenPoint (target.transform.position);
offset = target.transform.position - Camera.main.ScreenToWorldPoint (new Vector3 (Input.mousePosition.x, Input.mousePosition.y, screenSpace.z));
}
}
if (Input.GetMouseButtonUp (0)) {
_mouseState = false;
}
if (_mouseState) {
//keep track of the mouse position
var curScreenSpace = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, screenSpace.z);
//convert the screen mouse position to world point and adjust with offset
var curPosition = Camera.main.ScreenToWorldPoint (curScreenSpace) + offset;
//update the position of the object in the world
target.transform.position = curPosition;
}
}
GameObject GetClickedObject (out RaycastHit hit)
{
GameObject target = null;
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
if (Physics.Raycast (ray.origin, ray.direction * 10, out hit)) {
target = hit.collider.gameObject;
}
return target;
}
}

A better way to detect the cursor?

Goal: Detect when the cursor has entered a defined radius of the player.
Hello, I am in the process of trying to replicate the combat system from a game called CrossCode. The idea is that when the cursor is within a certain radius of the player, I will be able to switch to melee combat, and back to ranged once the cursor leaves this radius.
I have implemented one way I thought it could be done, however it feels slow or unreliable and I just wanted to know if there are any other methods I could possibly look into to achieve a smoother result.
Here is what I've done
attached to the player
void Update()
{
attackStyleSwitchRadius = colRef.radius;
playerCenter = colRef.transform.position;
if(Physics2D.OverlapCircle(playerCenter, attackStyleSwitchRadius, cursor))
{
meleeMode = true;
rangeMode = false;
}
else
{
meleeMode = false;
rangeMode = true;
}
}
And on a small 2D object I have this script so that it follows the cursor position.
void Update()
{
pos = Input.mousePosition;
gameObject.transform.position = Camera.main.ScreenToWorldPoint(pos);
}
when the small object enters the overlap circle it changes the bools around.
You can remove the collision detection overhead by doing something like this instead;
void Update ()
{
attackStyleSwitchRadius = colRef.radius;
playerCenter = colRef.transform.position;
var mouse = Input.mousePosition;
mouse.z = Vector3.Distance(Camera.main.transform.position, playerCenter);
var range = Vector2.Distance(Camera.main.ScreenToWorldPoint(mouse), playerCenter);
var inside = range < attackStyleSwitchRadius;
meleeMode = inside;
rangeMode = !inside;
}
Cursor
Make an object, name it cursor.
Add a small collider to the cursor object.
Add a script to the cursor object so its always at the mouses location.
Melee range zone
Add a GameObject as child of the player, name it MeleeRangeZone.
Add a collider to it, set it to be a Trigger. The size of this collider will be the players melee range,
Add a rigidbody to it so that collisions can be detected, but set the rigidbody to not rotate or change its position.
Add a script to the object and use the OnTriggerEnter and OnTriggerExit methods to detect whether or not the cursor has entered your melee zone.
You can now use the OnTriggerEnter and OnTriggerExit methods to switch between the players attack modes, meaning that when the cursor enters it changes to melee and when it exit it changes to ranged.
You can fire the ray to detect the location the cursor should have like this:
public LayerMask RaycastCollidableLayers;
public RaycastHit Hit;
public float CheckDistance = 200f;
public Transform Cursor;
void PerformRaycast(){
//Set up ray
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
//Fire ray
Physics.Raycast(ray, out Hit, CheckDistance + 0.1f, RaycastCollidableLayers);
if (Hit.collider == null)
{
//Debug.Log("Raycast hit nothing");
return;
}
else //Ray hit something
{
//Move cursor to Hit.point;
Cursor.position = Hit.point;
}
}

Drag a sprite by its 2D Polygon Collider component

I've got a draggable class that works great for dragging entire sprites and I'm trying to modify it to register dragging only within the defined 2D polygon collider component of the sprite object. I'm having a really hard time getting the drag to only register when I click within the boundaries of the polygon collider. Right now it's still dragging wherever I click-drag on the sprite including outside the boundaries of my polygon collider. I could really use some guidance on this. I've also attached an image to illustrate what I'm trying to achieve. Thanks!
PolygonCollider2D collider;
void Start ()
{
collider = transform.GetComponent<PolygonCollider2D>();
}
public void OnDrag (PointerEventData eventData)
{
Vector3 mousePosition = new Vector3(eventData.position.x, eventData.position.y, 0);
collider.transform.position = mousePosition;
if(transform.parent.gameObject == partsPanel)
transform.SetParent(dragLayer.transform);
if(transform.parent.gameObject == buildBoard)
transform.SetParent(dragLayer.transform);
}
AFAIK, The polygon collider we added to the sprite is editable. Goto inspector, collider component and there is a button which allow editing collider area. Adjust the points of this collider to cover just the desired area. This way only the desired area will receive touch events.
Ok, I know this is very old thread, but I had similar problem and I found a solution so I will post it here :)
Just create a class with this code and put it on your object
using UnityEngine;
[RequireComponent(typeof(RectTransform), typeof(Collider2D))]
public class Collider2DRaycastFilter : MonoBehaviour, ICanvasRaycastFilter
{
Collider2D myCollider;
RectTransform rectTransform;
void Awake()
{
myCollider = GetComponent<Collider2D>();
rectTransform = GetComponent<RectTransform>();
}
public bool IsRaycastLocationValid(Vector2 screenPos, Camera eventCamera)
{
var worldPoint = Vector3.zero;
var isInside = RectTransformUtility.ScreenPointToWorldPointInRectangle(
rectTransform,
screenPos,
eventCamera,
out worldPoint
);
if (isInside)
isInside = myCollider.OverlapPoint(worldPoint);
return isInside;
}
}

Categories

Resources