admin管理员组文章数量:1303480
using UnityEngine;
public class DragAndSwap : MonoBehaviour
{
private Camera cam;
private GameObject selectedObject;
private GameObject collidedObject;
private Vector3 offset;
private Vector3 originalPosition;
private Vector3 collidedOriginalPosition; // Store the original position of the collided object
void Start()
{
cam = Camera.main;
}
void Update()
{
if (Input.GetMouseButtonDown(0)) // Left mouse button click
{
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit)) // Check if we hit an object
{
selectedObject = hit.collider.gameObject;
originalPosition = selectedObject.transform.position; // Save original position
Vector3 screenPoint = cam.WorldToScreenPoint(selectedObject.transform.position);
offset = selectedObject.transform.position - cam.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
}
}
if (Input.GetMouseButton(0) && selectedObject) // While dragging
{
Vector3 screenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, cam.WorldToScreenPoint(selectedObject.transform.position).z);
Vector3 newWorldPosition = cam.ScreenToWorldPoint(screenPoint) + offset;
selectedObject.transform.position = new Vector3(newWorldPosition.x, newWorldPosition.y, originalPosition.z); // Keep Z position fixed
}
if (Input.GetMouseButtonUp(0) && selectedObject) // When released
{
if (collidedObject != null && collidedObject.CompareTag("Draggable"))
{
// Swap positions
Vector3 tempPosition = collidedObject.transform.position;
collidedObject.transform.position = originalPosition; // Move collided object to the original position of the selected object
selectedObject.transform.position = tempPosition; // Move selected object to the collided object's position
}
else
{
// No collision -> Move back to original position
selectedObject.transform.position = originalPosition;
}
selectedObject = null;
collidedObject = null; // Reset the collided object after swap or reset
}
}
void OnTriggerEnter(Collider other)
{
if (selectedObject != null && other.gameObject.CompareTag("Draggable"))
{
collidedObject = other.gameObject; // Store reference to the object we collided with
collidedOriginalPosition = collidedObject.transform.position; // Store the original position of the collided object
}
}
void OnTriggerExit(Collider other)
{
if (collidedObject == other.gameObject)
{
collidedObject = null; // Reset if the selected object moves away
}
}
}
I want the selected object to do swap and move into its correct position but the other object is moving into its correct position. The selected object after swapping with other object is not moving to the swapped position while it is moving into its original position. Please help what i am doing wrong in this code?
I had try to solve it step by step. I might the think the problem might be in selectedobject inalposition is not correctly stored and another raeson might be trigger function is not correct calling?
using UnityEngine;
public class DragAndSwap : MonoBehaviour
{
private Camera cam;
private GameObject selectedObject;
private GameObject collidedObject;
private Vector3 offset;
private Vector3 originalPosition;
private Vector3 collidedOriginalPosition; // Store the original position of the collided object
void Start()
{
cam = Camera.main;
}
void Update()
{
if (Input.GetMouseButtonDown(0)) // Left mouse button click
{
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit)) // Check if we hit an object
{
selectedObject = hit.collider.gameObject;
originalPosition = selectedObject.transform.position; // Save original position
Vector3 screenPoint = cam.WorldToScreenPoint(selectedObject.transform.position);
offset = selectedObject.transform.position - cam.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
}
}
if (Input.GetMouseButton(0) && selectedObject) // While dragging
{
Vector3 screenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, cam.WorldToScreenPoint(selectedObject.transform.position).z);
Vector3 newWorldPosition = cam.ScreenToWorldPoint(screenPoint) + offset;
selectedObject.transform.position = new Vector3(newWorldPosition.x, newWorldPosition.y, originalPosition.z); // Keep Z position fixed
}
if (Input.GetMouseButtonUp(0) && selectedObject) // When released
{
if (collidedObject != null && collidedObject.CompareTag("Draggable"))
{
// Swap positions
Vector3 tempPosition = collidedObject.transform.position;
collidedObject.transform.position = originalPosition; // Move collided object to the original position of the selected object
selectedObject.transform.position = tempPosition; // Move selected object to the collided object's position
}
else
{
// No collision -> Move back to original position
selectedObject.transform.position = originalPosition;
}
selectedObject = null;
collidedObject = null; // Reset the collided object after swap or reset
}
}
void OnTriggerEnter(Collider other)
{
if (selectedObject != null && other.gameObject.CompareTag("Draggable"))
{
collidedObject = other.gameObject; // Store reference to the object we collided with
collidedOriginalPosition = collidedObject.transform.position; // Store the original position of the collided object
}
}
void OnTriggerExit(Collider other)
{
if (collidedObject == other.gameObject)
{
collidedObject = null; // Reset if the selected object moves away
}
}
}
I want the selected object to do swap and move into its correct position but the other object is moving into its correct position. The selected object after swapping with other object is not moving to the swapped position while it is moving into its original position. Please help what i am doing wrong in this code?
I had try to solve it step by step. I might the think the problem might be in selectedobject inalposition is not correctly stored and another raeson might be trigger function is not correct calling?
Share Improve this question asked Feb 10 at 10:07 Hamza Abdul RazzaqHamza Abdul Razzaq 11 silver badge 1- correct position? is a bit ambiguous in this kind of situation so, to swap 2 items, you have itemA itemB and a tmp holder for remembering where one of them was. Such as, you set tmp to be itemA's position move A to B, and B to tmp, and they will now be swapped – BugFinder Commented Feb 10 at 10:21
1 Answer
Reset to default 1Just to get an overview of the current situation take for instance Object A and Object B on a scene the player (user) can select either one of them (any one to be specific) as both of the objects will have the MonoBehaviour script attached to them. In the case Object A is clicked on (selected variable is set) and the offset is also determined at the time of click to keep it away from the screen (maybe on a surface or something). Now as the selected object is set the following block of code can run:
if (Input.GetMouseButton(0) && selectedObject) // While dragging
{
Vector3 screenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, cam.WorldToScreenPoint(selectedObject.transform.position).z);
Vector3 newWorldPosition = cam.ScreenToWorldPoint(screenPoint) + offset;
selectedObject.transform.position = new Vector3(newWorldPosition.x, newWorldPosition.y, originalPosition.z); // Keep Z position fixed
}
now the position of the Object A (selected object is updated until the mouse button is not released). The Object B (collided object) is set by using a Tag check (not recommended but it can work). And when the trigger is Exited the Object B (collided Object) is set to null i.e the Object A no longer has a reference to it. On mouse button released the position of the Object A and Object B is swapped. And if the collided Object is null the Object A ( selected Object) moves back to its orignal position. Now from what I understand you are setting the Object B (collided Object) to null when the Trigger is exited. The Objects should swap perfectly fine unless and until they are in collision with each other when the collision ends i.e. they move away from the Trigger bounds they will not swap as the Object A no longer has a reference to the Object B (collided object) which is set to null when the trigger is exited.
void OnTriggerExit(Collider other) {
if (collidedObject == other.gameObject) {
collidedObject = null; // Reset if the selected object moves away
}
}
removing this block of code will make the code work as intended but it will be prone to error if you intend to swap the object with any latest collided object than removing it could be the easiest solution.
Tips to make the code better:
- Utilize the use of interfaces example "IDragable" to make the code reusable.
- IDragable might have a function "Drag" etc which later sets the position of the objects when mouse button will be released. This approach will help you seperate two different logics i.e. the swap and the mouse control logic.
Please reply to this comment for further queries I will try my best to help. And Notify me if the problem has been solved I will be grateful. I apologize in advance if I was unable to understand the scenario to maximum detail.
Thanks.
本文标签:
版权声明:本文标题:c# - I want the selected object to do swap and move into its correct position but the other object is moving into its correct po 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741722026a2394448.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论