Unity - Zoufalý výkřik o pomoc s definitivním vymýcením bugu

Podělte se o své zkušenosti s jinými jazyky.
Odpovědět
Uživatelský avatar
Vojtas
Příspěvky: 288
Registrován: srpen 6, 2011, 5:19 pm
Facebook: http://www.facebook.com/#!/pro
Kontaktovat uživatele:

Unity - Zoufalý výkřik o pomoc s definitivním vymýcením bugu

Příspěvek od Vojtas » únor 23, 2014, 8:44 am

Dobrý den! Zdravím po nějaké době.

Dovolím si oslovit ty z Vás, kteří se alespoň trochu orientují v Unity. Osobně jsem notorický anti-logik, anti-matematik, anti-češtin a anti-humanoid, takže se snažím jakýmkoliv způsobem zbavit bugu, resp. jen najít správné řešení problému:

Snažím se napodobit ohýbání papíru ve hře. S ohnutím není problém, ten nastává v momentě, kdy se ohyb snažím přesunout pravým tlačítkem. V tom bodě se ohyb ztratí jakýkoliv stud a začne rotovat a tančit zcela neregulovaně, jak by mohlo napovědět toto video (disponující příšernou kvalitou, omluvte, prosím):
http://www.youtube.com/watch?v=xTJfD_KBAzw

Chápu, že pitomější a drzejší věc nemohu učinit, protože mi uniká jakási základní logická nesmyslnost, nicméně, zde je můj nehorázný prasokód:

Kód: Vybrat vše

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class DeformSprite : MonoBehaviour {

	Transform target;
	Vector3 clickedPos = Vector3.zero;
	Vector3 dir;
	Vector3 midLine;
	Vector3 perpendicular;
	Vector3 currentMouse;
	Vector3 mousePos;
	Vector3 endPoint;
	Vector3 dif;
	Vector3 linePos;
	float yScale;
	float xScale;
	float scaleRatio;
	float a;
	float b;
	float cola;
	float colb;
	Matrix4x4 m;
	Quaternion originalRot;

	public Transform prefab;
	public int maximumChild = 1;
	[HideInInspector]
	public Vector3 originalClickedPos = Vector3.zero;

	private LayerMask bendLayers;
	private bool bend = false;
	private bool create = false;
	
	void Start () {
		originalClickedPos = Vector3.zero;
		dif = transform.position;
		m = Matrix4x4.TRS(dif, transform.rotation, Vector3.one).inverse;
		originalRot = transform.rotation;
		transform.rotation = Quaternion.AngleAxis(0,Vector3.forward);
		yScale = renderer.bounds.size.y;
		xScale = renderer.bounds.size.x;
		scaleRatio = xScale / yScale;
		transform.rotation = originalRot;
	}

	void OnMouseOver(){
		if(Input.GetButtonDown("Bend") && !bend && renderer.sortingOrder<maximumChild && transform.childCount == 0) {
			create = true;
			clickedPos = mousePos;
			bend = true;
		}

		if(Input.GetButtonDown("Unfold") && !bend && transform.childCount == 0 && renderer.sortingOrder!=0) {
			bend = true;
			target = gameObject.transform;

			DeformSprite targetDef = target.GetComponent<DeformSprite>();
			clickedPos = targetDef.originalClickedPos;
			clickedPos = mousePos;
		}
	}

	void FixedUpdate () {
		mousePos = Input.mousePosition;
		mousePos.z = -Camera.main.transform.position.z;
		mousePos = Camera.main.ScreenToWorldPoint(mousePos);
		dif = transform.position;
		currentMouse = mousePos;
		
		if((currentMouse != clickedPos) && create && prefab!=null){
			create = false;
			CreateFold();
		}

		if((Input.GetButton("Bend")) && bend && !create && target!=null){
			CountFold(gameObject.transform, target);
		}

		if((Input.GetButton("Unfold")) && bend && !create && target!=null){
			CountFold(target.transform.parent, target.transform);
		}


		if(Input.GetButtonUp("Bend")||Input.GetButtonUp("Unfold")){
			bend = false;
		}
	}

	private void CountFold(Transform solid, Transform tar){
		Debug.DrawLine(solid.position,tar.position);
		Debug.DrawLine(currentMouse, clickedPos, Color.red);
		dir = currentMouse - clickedPos;
		midLine = ( clickedPos + currentMouse ) / 2;
		perpendicular = new Vector3 ( dir.y, -dir.x, 0 );
		
		tar.position = ((Vector3.Project( -(midLine - dif), perpendicular) + dif) + midLine  - dif - dif/2) * 2 + Vector3.forward * -0.2f;
		tar.rotation = Quaternion.LookRotation( Vector3.forward, (clickedPos - solid.position) - (tar.position - solid.position)) * Quaternion.LookRotation( Vector3.forward, (currentMouse - solid.position)) * Quaternion.AngleAxis(-transform.localRotation.eulerAngles.z,Vector3.forward);

		midLine = RotatePointAroundPivot (midLine,dif, - solid.eulerAngles.z);
		perpendicular = m.MultiplyVector(perpendicular);
		a = (perpendicular.y/perpendicular.x);
		b = ((midLine.y - dif.y + yScale/2) - a * (midLine.x - dif.x + xScale/2))/yScale;
		
		int side = (int)Mathf.Sign(clickedPos.y - currentMouse.y);

		renderer.material.SetFloat("_a", a*scaleRatio);
		renderer.material.SetFloat("_b", b);
		renderer.material.SetFloat("_under", side);

		tar.renderer.material.SetFloat("_a", a*scaleRatio);
		tar.renderer.material.SetFloat("_b", b);
		tar.renderer.material.SetInt("_under", -side);
		tar.renderer.material.SetColor("_Color", Color.gray);
		tar.renderer.sortingOrder = solid.renderer.sortingOrder + 1;
		
		cola = perpendicular.y/perpendicular.x;
		colb = ((midLine.y - dif.y) - cola * (midLine.x - dif.x))/solid.localScale.y;
		
		gameObject.SendMessage("SetLine",new Vector2(cola,colb));
		tar.SendMessage("SetLine",new Vector2(cola,colb));
		tar.SendMessage("SetLineSide",-side);
	}
	
	private void CreateFold(){
		target = (Transform) Instantiate(prefab,mousePos,Quaternion.identity);

		target.transform.localScale = transform.localScale;
		Vector3 theScale = target.transform.localScale;
		theScale.x *= -1;
		target.transform.localScale = theScale;

		target.transform.parent = transform;

		Debug.Log (clickedPos);
		DeformSprite targetDef = target.GetComponent<DeformSprite>();
		targetDef.originalClickedPos = clickedPos;
	}
	
	private Vector2 RotatePointAroundPivot(Vector2 point, Vector2 pivot, float angles){
		Vector2 dir = point - pivot;
		dir = Quaternion.AngleAxis(angles, Vector3.forward) * dir;
		point = dir + pivot;
		return point;
	}
}
Tento script je přiřazen jak originálnímu tvaru, tak ohybu. Přes shader pak nastavuji linku neviditelnosti. Proměnné cola a colb jsou tytéž linie zapsané pro generování polygon collideru (ještě jednou děkuji za pomoc a trpělivost)...

Myslíte, že tušíte kde je chyba? Samozřejmě po nikom nechci řešení, ocením jakýkoli tip a výtku.
Děkuji a omlouvám se za zdlouhavost a moji omezenost.
Přeji hezký den!

PS: Rád si přečtu i kritiku celého toho kódu, jakýmkoli změnám jsem zcela nakloněn! Vím, že je to zvěrstvo, ale moje schopnosti dál nedosáhnou...
Více o mně a mých "hrách" na twitteru: https://twitter.com/VojtaKoci
Budu rád, podíváte-li se i na můj nový blog o všeobecném dění a mých nejen herních projektech: http://vojtakoci.blogspot.cz/

Ukaž Hru
Příspěvky: 42
Registrován: prosinec 18, 2013, 10:52 am
Facebook: https://www.facebook.com/CZSKUnity3D/?fref=ts
Kontaktovat uživatele:

Re: Unity - Zoufalý výkřik o pomoc s definitivním vymýcením

Příspěvek od Ukaž Hru » duben 23, 2014, 8:54 pm

Zkus napsat na https://www.facebook.com/CZSKUnity3D tam ti admini rádi poradí. Odpovídají do druhého dne.
ObrázekUNITY3D Nová česko slovenská komunita o Unity3D

www.forum.unitycesky.cz
www.unitycesky.cz

Ukaž Hru
Příspěvky: 42
Registrován: prosinec 18, 2013, 10:52 am
Facebook: https://www.facebook.com/CZSKUnity3D/?fref=ts
Kontaktovat uživatele:

Re: Unity - Zoufalý výkřik o pomoc s definitivním vymýcením bugu

Příspěvek od Ukaž Hru » březen 13, 2016, 9:09 pm

Zkus navštívit naši novou stránku a fórum zaměřenou na Unity3D tam ti určitě moderátor poradí co s tím.
Forum: http://forum.unitycesky.cz/
Web: http://forum.unitycesky.cz/
Facebook: https://www.facebook.com/CZSKUnity3D/?fref=ts
ObrázekUNITY3D Nová česko slovenská komunita o Unity3D

www.forum.unitycesky.cz
www.unitycesky.cz

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 1 host