- Home /
Highlighting and Moving an Object
Hello World! :)
I'm making a simple pvp 3D chess game and I have a few problems..
First of all, I would like to be able to click and drag a chess piece, so when clicked (while holding mouse button down) it automatically moves "up" just above other pieces and then I should be able to drag it around, and place it somewhere upon mouse button release. All I have is this code, which moves it awkwardly:
private var screenPoint: Vector3;
private var offset: Vector3;
private var curScreenPoint : Vector3;
private var curPosition : Vector3;
function Start () {
}
function Update () {
}
function OnMouseDown () {
screenPoint = Camera.main.WorldToScreenPoint(gameObject.transform.position);
offset = gameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
Screen.showCursor = false;
}
function OnMouseDrag() {
curScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);
curPosition = Camera.main.ScreenToWorldPoint(curScreenPoint) + offset;
transform.position = curPosition;
}
function OnMouseUp(){
Screen.showCursor = true;
}
Secondly, I would like to highlight an object using (I guess) OnMouseEnter and OnMouseExit, but again my code doesn't work! I have no errors, but it simply won't change my predefined defaultMaterial to OnHoverMaterial..?
var defaultMaterial : Material;
var onHoverMaterial : Material;
function OnMouseEnter(){
defaultMaterial = renderer.material;
renderer.material = onHoverMaterial;
}
function OnMouseExit(){
renderer.material = defaultMaterial ;
}
Thanks guys! :)
I didn't see any problem in the code, so I ran a quick test with your material changing script in Unity. It works fine. Are you sure you have the onHover$$anonymous$$aterial set correctly? Do you have a collider on the object?
Well, the code is the same as the one here, and I've applied Default$$anonymous$$aterial and OnHover$$anonymous$$aterial in Unity (as you can see in screenshot I just added to post) and I have a Box collider on an object. Nothing! :)
Answer by robertbu · Jan 25, 2013 at 04:36 PM
I'm not sure what is going on with your highlight. The code looks fine and works for me. Put a Debug.Log() statement inside the OnMouseEnter() to see if it is even being called. If not, replace a chess piece with a the Unity cube and test it. If the cube also has issues, I'd look for a collider between the camera and the box.
As for moving the chess piece, the trick here is to translate Y movement into Z movement. Assuming your chess board is on the XZ plane, you can save the initial position and then use the Y delta from that position as a Z delta from the Z's original position to move the piece back to front. The Y position would not change. As for picking the piece up, if you can live with an immediate jump, just translate your piece up right before line 14 by a fixed amount, and then translate it back down by the same amount in the OnMouseUp() function.
I did it, the problem was my pieces didn't have a $$anonymous$$esh Filter! :) Now I have another problem, pieces that I made in 3DS $$anonymous$$ax have several meshes for one piece, even tho I collapsed them in 3ds max, but I'll have to work that myself.. :)
As for the XZ movement, I'll give it a try, I'm still relatively new to scripting in .js but thx for your help!
You could put a box or capsule collider on your pieces until you have your issues sorted out in 3DS $$anonymous$$ax.
private var objPlane: Plane;
private var objTr: Transform;
private var cam: Camera;
private var hit: RaycastHit;
function Start (){
if (camera)
cam = camera;
else
cam = Camera.main;
}
function Update (){
if (Input.Get$$anonymous$$ouseButtonDown (0)){ // if left button pressed...
// and some object is under the mouse pointer...
if (Physics.Raycast(cam.ScreenPointToRay(Input.mousePosition), hit, 500)){
// and it has the right tag...
if (hit.transform.tag == "player"){
// starts dragging it
StartCoroutine ("DragObject");
}
}
}
}
function DragObject(){
objTr = hit.transform; // save object transform
// create a plane at object position
objPlane = Plane(Vector3.up, objTr.position);
while (Input.Get$$anonymous$$ouseButton (0)){ // loop while button pressed
// create a ray from mouse position perpendicular to screen
var ray = cam.ScreenPointToRay (Input.mousePosition);
var distance: float;
// get the distance from mouse pointer to the plane
objPlane.Raycast(ray, distance);
// define the new position
var newPos = ray.GetPoint(distance);
// avoid modification in the disabled axis
if (!xAxis) newPos.x = objTr.position.x;
if (!zAxis) newPos.z = objTr.position.z;
// move to newPos a little step each frame
objTr.position = Vector3.Lerp(objTr.position, newPos, speed * Time.deltaTime);
// suspend execution until next frame
yield;
}
}
I've found this code. Should it work? Because it doesn't :) I hope it's not to rude to just paste the code and ask for help..
Pasting code you did not work on and asking for other to fix it is not in the spirit of the list. Plus it is better to link to other's code rather than past it in so that context and credit is available. Plus this really should have been a new question. And it is not in your best interest. Ultimately if you are going to complete your game, you are going to have to understand the scripts you are using.
As for the new code, it approaches the problem in a very different (and a bit more complicated) way than the original code. The original code makes each piece responsible for moving itself. This new code moves all the pieces from "outside." Which approach to use will depend a lot on the structure and goal of the rest of your game.
Oh, right.. Thought so, still decided to give it a try. Thanks! I'll take my time and work thru a bunch of tutorials.
Answer by KraljCro · Jan 28, 2013 at 10:15 AM
Ok, I got highlight material to work, my pieces move up on y axis when clicked and move along x and z when dragged, I disabled rotation when dragged and put a Debug.DrawRay to see where the piece will fall.
But, this last thing bugs me. Instead of DrawRay, it would be nicer if the area beneath the piece, where the shadow would be projected on the chess board, could 'glow' let's say red. For what I learned so far, I'd need to use RaycastHit, so the code would look something like this: function Update(){
var rayDown = transform.TransformDirection(0, 0, -5);
var hit : RaycastHit;
if(Physics.Raycast(transform.position, rayDown, 5)){
if(hit.collider.gameObject.name == "Board"){
//Somehow make a glow highlight on board
}
}
}