Не могу разобраться в скрипте.

Программирование на Юнити.

Не могу разобраться в скрипте.

Сообщение Valera01 17 сен 2011, 09:13

Привет.
Я скачал с оф. сайта скрипт разрушения объектов( forum.unity3d.com/threads/57994-Simple-Fracture-Script-v-1.01 )
И не могу в нем разобраться.
Проблема вот в чем: После того, как я применяю к объекту(боксу) скрипт и ломаю его, то он рассыпается на кусочки, но все кроме одного куски падают сквозь тиррейн.Как мне это решить?
Синтаксис:
Используется javascript
var fractureToPoint = false;
var totalMaxFractures = 3;
var forcePerDivision = 20.0;
var minBreakingForce = 0.0;
var maxFracturesPerCall = 3;
var randomOffset = 0.0;
var minFractureSize : Vector3 = Vector3.zero;
var grain : Vector3 = Vector3.one;
var useCollisionDirection = 0.0;
var fractureAtCenter = false;
var smartJoints = false;
var destroyAllAfterTime = 0.0;
var destroySmallAfterTime = 0.0;
var instantiateOnBreak : GameObject;
var totalMassIfStatic = 1.0;
private var joints : Joint[];
//-------------------------------------------------------------------
function Start () {
        if (rigidbody) {
                temp = new Array();
                for(j in FindObjectsOfType(Joint)) {
                        if (j.connectedBody == rigidbody) {
                                temp.Add(j);
                                joints  = temp.ToBuiltin(Joint);
                        }
                }
        }
}
//-------------------------------------------------------------------
function OnCollisionEnter (collision : Collision) {
        point=collision.contacts[0].point;
        vec = collision.relativeVelocity*UsedMass(collision);
        FractureAtPoint(point,vec);
}
//-------------------------------------------------------------------
function FractureAtPoint (hit : Vector3, force : Vector3) {
        if (force.magnitude < Mathf.Max(minBreakingForce,forcePerDivision)) {return;}
        iterations =  Mathf.Min(Mathf.RoundToInt(force.magnitude/forcePerDivision),Mathf.Min(maxFracturesPerCall,totalMaxFractures));
        point = transform.worldToLocalMatrix.MultiplyPoint(hit);
        Fracture(point,force,iterations);
}
//-------------------------------------------------------------------
function Fracture (point : Vector3, force : Vector3, iterations : float) {
        if (instantiateOnBreak && force.magnitude >= Mathf.Max(minBreakingForce,forcePerDivision)) {
                Instantiate(instantiateOnBreak,transform.position,transform.rotation);
                instantiateOnBreak = null;
        }
        while (iterations > 0) {
                // if we are smaller than our minimum fracture size in any dimension, no more divisions.
                if (totalMaxFractures == 0 || Vector3.Min(gameObject.GetComponent(MeshFilter).mesh.bounds.size,minFractureSize) != minFractureSize) {
                        if (destroySmallAfterTime >= 1) {
                                Destroy(GetComponent(MeshCollider),destroySmallAfterTime-1);
                                Destroy(gameObject,destroySmallAfterTime);
                        }
                        totalMaxFractures = 0;
                        return;
                }
                totalMaxFractures -= 1;
                iterations -= 1;
                // define the splitting plane by the user settings.
                if(fractureAtCenter){point=GetComponent(MeshFilter).mesh.bounds.center;}
                vec = Vector3.Scale(grain,Random.insideUnitSphere).normalized;
                sub = transform.worldToLocalMatrix.MultiplyVector(force.normalized)*useCollisionDirection*Vector3.Dot(transform.worldToLocalMatrix.MultiplyVector(force.normalized),vec);
                plane = Plane(vec-sub,Vector3.Scale(Random.insideUnitSphere,GetComponent(MeshFilter).mesh.bounds.size)*randomOffset+point);
                // create the clone
                newObject = Instantiate(gameObject,transform.position,transform.rotation);
                if (rigidbody) {newObject.rigidbody.velocity = rigidbody.velocity;}
                // arrays of the verts
                var vertsA =  gameObject.GetComponent(MeshFilter).mesh.vertices;
                var vertsB =  newObject.GetComponent(MeshFilter).mesh.vertices;
                average = Vector3.zero;
                for (i in vertsA) {
                        average += i;
                }
                average /= gameObject.GetComponent(MeshFilter).mesh.vertexCount;
                average -= plane.GetDistanceToPoint(average)*plane.normal;
                //-------------------------------------------------------------------
                broken = 0;
                // split geometry along plane
                if (fractureToPoint) {
                        for (i=0;i<gameObject.GetComponent(MeshFilter).mesh.vertexCount;i++) {
                                if (plane.GetSide(vertsA[i])) {
                                        vertsA[i] = average;
                                        broken += 1;
                                }
                                else {
                                        vertsB[i] = average;
                                }
                        }
                }
                else {
                        for (i=0;i<gameObject.GetComponent(MeshFilter).mesh.vertexCount;i++) {
                                if (plane.GetSide(vertsA[i])) {
                                        vertsA[i] -= plane.GetDistanceToPoint(vertsA[i])*plane.normal;
                                        broken += 1;
                                }
                                else {
                                        vertsB[i] -= plane.GetDistanceToPoint(vertsB[i])*plane.normal;
                                }
                        }
                }
                // IMPORTANT: redo if we have a problem splitting; without this, we will get a lot of non-manifold meshes, convexhull errors and maybe even crash the game.
                if (broken == 0 || broken == gameObject.GetComponent(MeshFilter).mesh.vertexCount) {
                        totalMaxFractures += 1;
                        iterations += 1;
                        Destroy(newObject);
                        // this yield is here JUST so that when a large amount of objects are being broken, the screen doesn't freeze for a long time. It allows the screen to refresh before we're finnished, but if you don't, it might slow the script down trying to break a loop of bad planes.
                        yield;
                }
                // if all's fine, apply the changes to each mesh
                else {
                        gameObject.GetComponent(MeshFilter).mesh.vertices = vertsA;
                        newObject.GetComponent(MeshFilter).mesh.vertices = vertsB;
                        gameObject.GetComponent(MeshFilter).mesh.RecalculateNormals();
                        newObject.GetComponent(MeshFilter).mesh.RecalculateNormals();
                        gameObject.GetComponent(MeshFilter).mesh.RecalculateBounds();
                        newObject.GetComponent(MeshFilter).mesh.RecalculateBounds();
                        if (gameObject.GetComponent(MeshCollider)) {
                                gameObject.GetComponent(MeshCollider).sharedMesh = gameObject.GetComponent(MeshFilter).mesh;
                                newObject.GetComponent(MeshCollider).sharedMesh = newObject.GetComponent(MeshFilter).mesh;
                        }
                        // if we weren't using a convexhull, the pieces colliders won't work right. It's best for everyone if we just remove them.
                        else {
                                Destroy(collider);
                                Destroy(gameObject,1);
                        }
                        // smartjoints will allow joints to function properly.
                        if (smartJoints) {
                                jointsb = GetComponents(Joint);
                                if (jointsb){
                                        // Basically, it goes through each joint and sees if the object A or B are closer to the connected body. Whichever is closer keeps the joint.
                                        for (i=0;i<jointsb.length;i++){
                                                if (jointsb[i].connectedBody != null && plane.GetSide(transform.worldToLocalMatrix.MultiplyPoint(jointsb[i].connectedBody.transform.position))) {
                                                        if (jointsb[i].gameObject.GetComponent(SimpleFracture).joints) {
                                                                // If we're attached to a fracture object and the new object is closer, switch the connected object's joint variable at the correct index.
                                                                for (c in jointsb[i].gameObject.GetComponent(SimpleFracture).joints) {
                                                                        if (c == jointsb[i]) {c = newObject.GetComponents(Joint)[i];}
                                                                }
                                                        }
                                                        Destroy(jointsb[i]);
                                                }
                                                else {
                                                        Destroy(newObject.GetComponents(Joint)[i]);
                                                }
                                        }
                                }
                                // joints contains all joints this object is attached to. It checks if the joint still exists, and if the new object is closer. If so, changes the connection. It then removes the joint from the joints variable at the correct index.
                                if (joints){
                                        for (i=0;i<joints.length;i++){
                                                if (joints[i] && plane.GetSide(transform.worldToLocalMatrix.MultiplyPoint(joints[i].transform.position))) {
                                                        joints[i].connectedBody = newObject.rigidbody;
                                                        temp = new Array(joints);
                                                        temp.RemoveAt(i);
                                                        joints = temp.ToBuiltin(Joint);
                                                }
                                                else {
                                                        temp = new Array(joints);
                                                        temp.RemoveAt(i);
                                                        newObject.GetComponent(SimpleFracture).joints = temp.ToBuiltin(Joint);
                                                }
                                        }
                                }
                        }
                        // if we don't have smartJoints, the code is much shorter. destroy all joints.
                        else {
                                if (GetComponent(Joint)) {
                                        for (i=0;i<GetComponents(Joint).length;i++){
                                                Destroy(GetComponents(Joint)[i]);
                                                Destroy(newObject.GetComponents(Joint)[i]);
                                        }
                                }
                                if (joints) {
                                        for (i=0;i<joints.length;i++){
                                                Destroy(joints[i]);
                                        }
                                        joints = null;
                                }
                        }
                        // if the script is attached to a static object, make it dynamic. If not, divide the mass up.
                        if (!rigidbody) {
                                gameObject.AddComponent(Rigidbody);
                                newObject.AddComponent(Rigidbody);
                                rigidbody.mass = totalMassIfStatic;
                                newObject.rigidbody.mass = totalMassIfStatic;
                        }
                        gameObject.rigidbody.mass *= 0.5;
                        newObject.rigidbody.mass *= 0.5;
                        gameObject.rigidbody.centerOfMass = transform.worldToLocalMatrix.MultiplyPoint3x4(gameObject.collider.bounds.center);
                        newObject.rigidbody.centerOfMass = transform.worldToLocalMatrix.MultiplyPoint3x4(newObject.collider.bounds.center);
                       
                        newObject.GetComponent("SimpleFracture").Fracture(point,force,iterations);
                       
                        if (destroyAllAfterTime >= 1) {
                                Destroy(newObject.GetComponent(MeshCollider),destroyAllAfterTime-1);
                                Destroy(GetComponent(MeshCollider),destroyAllAfterTime-1);
                                Destroy(newObject,destroyAllAfterTime);
                                Destroy(gameObject,destroyAllAfterTime);
                        }
                        // this yield is here JUST so that when a large amount of objects are being broken, the screen doesn't freeze for a while.
                        yield;
                }// if not broken end
        }// while itterations end
        if (totalMaxFractures == 0 || Vector3.Min(gameObject.GetComponent(MeshFilter).mesh.bounds.size,minFractureSize) != minFractureSize) {
                if (destroySmallAfterTime >= 1) {
                        Destroy(GetComponent(MeshCollider),destroySmallAfterTime-1);
                        Destroy(gameObject,destroySmallAfterTime);
                }
                totalMaxFractures = 0;
        }
}
//--------------------------------------------------------------
function UsedMass (collision : Collision) {
        if (collision.rigidbody) {
                if (rigidbody) {
                        if (collision.rigidbody.mass < rigidbody.mass) {
                                return (collision.rigidbody.mass);
                        }
                        else {
                                return (rigidbody.mass);
                        }
                }
                else {
                        return (collision.rigidbody.mass);
                }
        }
        else if (rigidbody) {
                return (rigidbody.mass);
        }
        else {return (1);}
}
Последний раз редактировалось Valera01 19 сен 2011, 15:24, всего редактировалось 1 раз.
Valera01
UNец
 
Сообщения: 12
Зарегистрирован: 01 сен 2011, 13:09

Re: Не могу разобраться в скрипте.

Сообщение ArtUni3d 19 сен 2011, 02:46

Если вы выложите сюда код, будет больше шансов получить ответ. Люди не любят лазить по левым ссылкам, особенно когда из нужно сначала выделить, скопировать и вставить в строку адреса)
Аватара пользователя
ArtUni3d
UNITрон
 
Сообщения: 249
Зарегистрирован: 27 апр 2011, 22:12

Re: Не могу разобраться в скрипте.

Сообщение seaman 19 сен 2011, 10:24

If the object is static, then all it's pieces become rigidbodies after splitting.

Попробуйте сделать Ваш объект Static.
seaman
Адепт
 
Сообщения: 8352
Зарегистрирован: 24 янв 2011, 12:32
Откуда: Самара

Re: Не могу разобраться в скрипте.

Сообщение lol 23 окт 2011, 10:56

Чтобы не создавать новую тему по этому скрипту спрошу здесь.
А как вызвать метод ломания (FractureAtPoint) из другого скрипта?
Скрипт SimpleFracture - это js.

Судя по справке, что вроде:
Синтаксис:
Используется csharp
SimpleFracture pFr =gameObject.GetComponent("SimpleFracture") as SimpleFracture;
pFr.FractureAtPoint(m_pGameObject.transform.position, new Vector3(0.5f, 0.5f, 1.0f));
 


Но не компилиться:
The type or namespace name `SimpleFracture' could not be found. Are you missing a using directive or an assembly reference?

P.S. вызывается из скрипта C#
P.P.S Скрипт в папке именно так и называется SimpleFracture
lol
Старожил
 
Сообщения: 508
Зарегистрирован: 15 ноя 2009, 10:48
Откуда: Москва

Re: Не могу разобраться в скрипте.

Сообщение lol 24 окт 2011, 20:12

По сути мне надо просто из C# вызывать метод из скрипта JS. Разве при этом могут быть проблемы? Я пробовал подставлять другой скрипт(из тех, что по умолчанию есть в проекте) - та же фигня. Может есть какая-то особенность?
lol
Старожил
 
Сообщения: 508
Зарегистрирован: 15 ноя 2009, 10:48
Откуда: Москва

Re: Не могу разобраться в скрипте.

Сообщение waruiyume 24 окт 2011, 22:30

Script compilation
Засунуть (js) в папку Plugins.
Аватара пользователя
waruiyume
Адепт
 
Сообщения: 6143
Зарегистрирован: 30 окт 2010, 05:03
Откуда: Ростов на Дону

Re: Не могу разобраться в скрипте.

Сообщение lol 25 окт 2011, 21:39

Наверное в этом дело, вот только у меня все скрипты в Standard Assets\Scripts, т.е. мне надо сначала сделать, чтобы мой C# компилился после JS, а для этого его надо выкинуть из Standard Assets что ли.

Вообще, их описание я здесь не понял:
1. All scripts in "Standard Assets", "Pro Standard Assets" or "Plugins" are compiled first.
Все скрипты в этой папке компилируются первыми. Имеются ввиду все скрипты во всех под папках этой папки(Standard Assets допустим) или (судя по наличию пунктов 2 и 3) действительно только скрипты в этой папке, без учета подпапок?
lol
Старожил
 
Сообщения: 508
Зарегистрирован: 15 ноя 2009, 10:48
Откуда: Москва


Вернуться в Скрипты

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6