- Home /
Create 'Tippex' for a drawn line.
Hello - hear me out, it sounds odd. I have a 2d physics game for IOS, where the player draws lines (made up of ink splats):
these ink splats have a script which creates a sort of continuous collider, made of many box colliders, so a 'ball' rolls smoothly down them. Now after having a few people test my game the general feedback is that rather than restarting a level if you mess up these lines, add in an eraser, i thought, since its a pen, a 'tippex' type liquid corrector is better. So, i already have vectrosity and decided to use it. I have the white line in place and you switch between pen and 'tippex' easily, and i have layered it so it sees and removes the inks and colliders when over it, but it misses a few, due to the speed of update. I then put it in to fixed update so it raycasts more, but it still misses a couple. So i need to know, is there a better way to check if the touch position hits one of these colliders - ie not using raycasts,, as fixed update isnt fast enough. And if not, any ideas how to go about upping the framerate? ive optimised the game already, rigorously, so im a bit stuck.
Tippex line :
(basic test line, need to smooth it etc)
PS. sorry about the essay, but i know its better to have too much detail than too little.
Answer by whydoidoit · Jul 27, 2012 at 06:48 PM
So you won't fix it by using a different frame rate - there's always going to be a case where it misses. It sounds to me line you need to ray cast from the previous position of the line in the last Update to the current position making sure that such a line would intersect the plane on which the ink spots exist. You might also cast a sphere rather than a line to make sure that the width of the tippex brush is simulated.
thank you for your reply, agreed. This makes much more sense.
Ive tried making the spherecast work and im going wrong somewhere, do you think you could have a quick look? much appreciated if so.
function FixedUpdate(){ if (hudScript.tipexOn){ if (Input.touchCount == 1){ thisPos = Input.touches[0].position; Debug.Log(thisPos); if (Physics.SphereCast(lastPos, 1.0, (lastPos-thisPos).normalized, hit, Vector3.Distance(thisPos, lastPos))){ if (hit.collider.name == "InkCol"){ hitInk = hit.collider.gameObject; Destroy(hitInk); Debug.Log(hitInk); } } lastPos = thisPos; } } }
the code stops at if(Physics.Spherecast)... im obviously missing something extremely stupid, so i think its time to ask for help.
thanks again.
One thing - it's not a good idea to do input in FixedUpdate as depending on the computer and the frame rate inputs can be missed or doubled up - Update is the right place for this code.
Otherwise my concern would be that the 0 z position of a screen touch doesn't intersect with where you plot the inkspots (are they at z=0) - we should probably be converting those touch positions before the cast to fit world space. Normally that would be using Camera.main.ScreenToWorldPoint where we'd specify the z coordinate that was appropriate.
so something like this then..
var ray = Camera.main.ScreenToWorldPoint (lastPos); if (Physics.SphereCast(ray, 1.0, (lastPos-thisPos).normalized, hit, Vector3.Distance(thisPos, lastPos))){
(would obviously test myself but not at the mac right now) :)
oh and thanks for the pointer, will stick it in Update.
Yes, normally you would also specify a z position in world units from the camera.