I have a sphere in that is moving foward and I need it to follow my finger smoothly when it swipes on the screen but only in the x axis.
I trying to make the exact movent like Rolling Sky, Color Road
The ball Should follow my finger when it swipes in the x axis and move smoothly.
Just like in the games I mention before.
I try OnMouseDrag and a lot of ways but it dont work correctly beacuse it dont dont follow the finger or it dont move while finger is swiping.
From what I understand, it seems you want to get the position of the user's finger and move the ball accordingly?
You could achieve this with Touch.position
Example:
private void Update()
{
Touch touch = Input.GetTouch(0); // Get the touch data for the first finger
Vector2 position = touch.position; // Get the position in screen-space
Vector3 worldPosition = Camera.main.ScreenToWorldPoint(position); // Convert the position to world space
Vector3 ballPosition = ball.transform.position;
ball.transform.position = new Vector3(worldPosition.x, ballPosition.y, ballPosition.z); // Move the ball
}
I think you should handle the input separately from the sphere.
Put this on a script to detect the swiping on the screen.
bool inputBegan = false;
Vector2 beganPosition;
void Update()
{
if (!inputBegan && Input.GetMouseButtonDown (0))
{
inputBegan = true;
beganPosition = Input.mousePosition;
}
else if (inputBegan && Input.GetMouseButtonUp (0))
{
//If you want a threshold you need to change this comparison
if (beganPosition.x > Input.mousePosition)
{
MoveBallLeft ();
}
else
{
MoveBallRight ();
}
inputBegan = false;
}
}
The movement of the balls you can achieve it adding or substracting Vector2.right * movingDistance to the sphere Transform if you want it to teleport or making the sphere move slowly using a targetPosition and currentPosition and each Update cycle add a little bit of transform distance.
I solved it doing this and setting the variable NavigationMultiplier to 10000
Related
want to make a game where there is a 2D ball which moves to the position of the cursor. To get the position of the cursor, I use this code:
Vector2 PixelPos = Input.mousePosition;
Then to convert the screen position to world position I use this code:
Vector2 Pos = Camera.main.ScreenToWorldPoint(PixelPos);
The problem is that the main camera move up so that if forces the player to move. But when it move I get some weird movement with the ball.(as the camera is moving up it is always moving the ball)
Is there an alternate way to make this work??
Or more simply can I replace this piece of code:
Vector2 Pos = Camera.main.ScreenToWorldPoint(PixelPos);
with some other things which does not require a camera to convert the screen positions to world position?
Thanks!
Since you want the cursor to be moved only by the player and to be updated relative to world space, not screen space, you need to implement a virtual cursor that exists in world space.
First, create your virtual cursor as a GameObject. On Update you can update its position with
float sensitivity = 1f;
transform.position += sensitivity * new Vector2(
Input.GetAxis("Mouse X"),
Input.GetAxis("Mouse Y")
);
Then, instead of using the camera to find the cursor position, you just check the `transform.position` of that virtual cursor `GameObject`.
Second, you'll need to lock the built-in cursor. You can do that with
Cursor.lockState = CursorLockMode.Locked;
If you need to undo that (for instance, if you bring up a menu, and need to use the regular cursor without moving the virual cursor around), then you can use:
Cursor.lockState = CursorLockMode.None;
or, if you need the cursor to stay in the window:
Cursor.lockState = CursorLockMode.Confined;
If you only want to move the ball to the last position clicked/touched then here is an easier solution.
Keep track of the goal position for the ball, and if one has been set yet:
private Vector2 moveGoalPos;
private bool moveGoalSet= false;
Only change moveGoalPos on frames where the mouse is clicked/the screen is touched.:
bool isTouched;
if (isMouseEnable) {
isTouched = Input.GetMouseButtonDown(0);
PixelPos = Input.mousePosition;
} else {
isTouched = Input.touchCount > 0;
Touch touch = Input.GetTouch(0);
PixelPos = touch.position;
}
if (isTouched) {
moveGoalPos= Camera.main.ScreenToWorldPoint(PixelPos);
moveGoalSet= true;
}
However, on every frame, you'll want to move the ball to the world space moveGoalPos (only if a goal has been set):
if (moveGoalSet) {
Vector2 OffsetPos = moveGoalPos + CursorOffSet;
GCursor.transform.position = OffsetPos;
print(OffsetPos);
Vector2 LerpPos = Vector2.Lerp(rb.transform.position, OffsetPos, 0.05f);
rb.MovePosition(LerpPos);
}
When you need to stop the ball from moving to the last touched/clicked position (for instance, if you change or reset a level), you'll need to reset moveGoalSet:
moveGoalSet = false;
I am trying to create a player movement along the x-axis based on finger position.
What I need to Happen: Not multi-Touch. I want it so a player can put a single finger down and grab that position. Then check to see if the player dragged finger along screen on x-axis and move player left or right based off where they dragged finger from first touch.
So if they touch the screen and if drag left: move left by speed and if it changes to drag right move right by speed.
Any help would be Awesome.
The easiest way would be to stored first touch position and then compare the X with that position:
public class PlayerMover : MonoBehaviour
{
/// Movement speed units per second
[SerializeField]
private float speed;
/// X coordinate of the initial press
// The '?' makes the float nullable
private float? pressX;
/// Called once every frame
private void Update()
{
// If pressed with one finger
if(Input.GetMouseButtonDown(0))
pressX = Input.touches[0].position.x;
else if (Input.GetMouseButtonUp(0))
pressX = null;
if(pressX != null)
{
float currentX = Input.touches[0].position.x;
// The finger of initial press is now left of the press position
if(currentX < pressX)
Move(-speed);
// The finger of initial press is now right of the press position
else if(currentX > pressX)
Move(speed);
// else is not required as if you manage (somehow)
// move you finger back to initial X coordinate
// you should just be staying still
}
}
`
/// Moves the player
private void Move(float velocity)
{
transform.position += Vector3.right * velocity * Time.deltaTime;
}
}
WARNING: this solution will only work for devices with touch input available (because of Input.touches use).
using the code #programmer provided in this answer: Detect swipe gesture direction
You can easily detect the direction you are swiping/dragging. Replace the Debug
void OnSwipeLeft()
{
Debug.Log("Swipe Left");
}
void OnSwipeRight()
{
Debug.Log("Swipe Right");
}
With functions that move your character. If you use RigidBody to move your character you can use https://docs.unity3d.com/ScriptReference/Rigidbody.MovePosition.html. If its a normal object, you can move it by tweaking the transform.position.
If you need more information on how to move rigidbody\normal objects let me know what type of game you have and more details on how you set up the player.
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;
}
}
I have a class below that I attach to a object in order to make it rotate around its pivot. I sent the pivot of the sprite via the inspector.
This works exactly how I want it too, BUT the issue I am having is that whenever I touch and drag it, and then touch and drag it again, it snaps to a new position.
What I would like for it to do is, when it is rotated and then rotated again, the sprite stays in its same rotation and not snap to a new position and I would like the angle of the sprite to be reset to 0. The next then is that I want the angle to continually rotate. So if I rotate it in the positive direction, the angle should keep increasing in the positive direction and not change..Such as 0---> 360 ----> 720 -----> etc, etc. And then when the mouse is released, the sprite stays in the same position but the angle is now set back to 0. And then when clicked again to rotate, it rotates from that exact position.
Here is my code thus far which works well for rotating, but I would like to modify it to achieve the above scenario. Any help with this?
public class Steering : MonoBehaviour {
float prevAngle,wheelAngle,wheelNewAngle = 0;
public SpriteRenderer sprite;
void Start () {
}
void Update () {
}
public float GetAngle(){
return wheelAngle;
}
void OnMouseDrag(){
Vector3 mouse_pos = Input.mousePosition;
Vector3 player_pos = Camera.main.WorldToScreenPoint(this.transform.position);
mouse_pos.x = mouse_pos.x - player_pos.x;
mouse_pos.y = mouse_pos.y - player_pos.y;
wheelNewAngle = Mathf.Atan2 (mouse_pos.y, mouse_pos.x) * Mathf.Rad2Deg;
if (Input.mousePosition.x > sprite.bounds.center.x) {
wheelAngle += wheelNewAngle - prevAngle;
} else {
wheelAngle -= wheelNewAngle - prevAngle;
}
this.transform.rotation = Quaternion.Euler (new Vector3(0, 0, wheelAngle));
Debug.Log (wheelAngle);
prevAngle = wheelNewAngle;
}
void OnMouseUp(){
prevAngle = wheelNewAngle;
wheelAngle = 0;
}
}
By angle of the sprite, do you mean the rotation? I'm not sure how the position is changing if there's nothing in your code doing that. Does it always move to the same position? I'm having a little trouble visualizing how your system is supposed to look but I hope this helps.
It looks like you might want to store the previous mouse position so you can get the relative amount to rotate each frame.
At the top:
Vector3 prevMousePos = Vector3.zero;
This method will help get the position when the player pressed:
void OnMouseDown(){
prevMousePos = Input.mousePosition;
}
Then in OnMouseDrag() get the difference between the two mouse positions to get the relative position (if you moved the mouse left, right, up, or down since pressing):
Vector3 mouseDiff = Input.mousePosition - prevMousePos;
With this it will use the relative mouse position after pressing instead of the current one, which should smooth things out.
I try to move my character but he moves through the border of the scene.
When I debug it sayscharTransform has 0 0 0 coords in Vector3.
Transform charTransform;
float leftHorizontalBound;
float rightHorizontalBound;
void Start()
{
charTransform = this.transform;
leftHorizontalBound = camera.ViewportToWorldPoint (new Vector3 (0,0, camera.nearClipPlane)).x;
rightHorizontalBound= camera.ViewportToWorldPoint (new Vector3 (1,0, camera.nearClipPlane)).x;
}
void Update()
{
if(charTransform.position.x <= leftHorizontalBound)
{
charTransform.position = new vector2(leftHorizontalBound + 0.1f);
return;
}
if(charTransform.position.x >= rightHorizontalBound)
{
charTransform.position = new vector2(rightHorizontalBound - 0.1f);
return;
}
//MAKE HERE YOUR MOVEMENT BASED ON INPUT.
}
i cant exactly say what is your problem and wish you assume your problem more accurate but i think you are working something like a boad game with a fixed camera and something like a ball always moves and you just want to keep that object in the scene.
in your code you defined a position by variables and made a position check for every frame. thats not what basically is done in unity and there will be problems. you can make an empty object and put in on the borders you want and check the position of that object with your moving object.
your next way is make an object and add a collider component to it. if your game is 3d add a collider and if its 2d game add a 2d collider and a collider to moving object and after that it never moves toward the borders but still there will be some limits so if it didnt work i think you should add a rigidBody to both of them.