СИМУЛЯЦИЯ РЕЗИНОВЫХ ОБЪЕКТОВ Unity 3d

Скрипты 1415 Гость 05.12.2024

Внимане!

Чтобы использовать — просто кидаем скрипт на любой объект. У объекта должен быть VertexColor, чтоб определить интенсивность эффекта.

Назвать скрипт RubberEffect.cs:

using UnityEngine;
using System.Collections;

public class RubberEffect : MonoBehaviour
{

    public RubberType Presets;

    public enum RubberType
    {
        Custom,
        RubberDuck,
        HardRubber,
        Jelly,
        SoftLatex
    }

    public float EffectIntensity = 1;
    public float gravity = 0;
    public float damping = 0.7f;
    public float mass = 1;
    public float stiffness = 0.2f;

    private Mesh WorkingMesh;
    private Mesh OriginalMesh;
    private float[] ColorIntensity;
    private VertexRubber[] vr;
    private Vector3[] V3_WorkingMesh;

    private bool sleeping = true;

    private Vector3 last_world_position;
    private Quaternion last_world_rotation;


    internal class VertexRubber
    {
        public int indexId;
        public float v_gravity;
        public float v_mass;
        public float v_stiffness;
        public float v_damping;
        public Vector3 pos;
        public Vector3 force;
        public Vector3 acc;
        public Vector3 last_pos, last_acc, last_force, last_vel;
        public bool v_sleeping = false;

        Vector3 vel = new Vector3();

        public VertexRubber(Vector3 v_target, float m, float g, float s, float d)
        {
            v_gravity = g;
            v_mass = m;
            v_stiffness = s;
            v_damping = d;
            pos = v_target;
        }

        public void update(Vector3 target)
        {

            if (!v_sleeping)
            {


                force.x = (target.x - pos.x) * v_stiffness;
                acc.x = force.x / v_mass;
                vel.x = v_damping * (vel.x + acc.x);
                pos.x += vel.x;

                force.y = (target.y - pos.y) * v_stiffness;
                force.y -= v_gravity / 10;
                acc.y = force.y / v_mass;
                vel.y = v_damping * (vel.y + acc.y);
                pos.y += vel.y;

                force.z = (target.z - pos.z) * v_stiffness;
                acc.z = force.z / v_mass;
                vel.z = v_damping * (vel.z + acc.z);
                pos.z += vel.z;

                if ((pos == last_pos) && (acc == last_acc) && (vel == last_vel) && (force == last_force)) v_sleeping = true;

                last_pos = pos;
                last_acc = acc;
                last_vel = vel;
                last_force = force;
            }

        }

    }

    
    void Start(){

        Debug.Log(Presets);
        MeshFilter filter = (MeshFilter)GetComponent(typeof(MeshFilter));
        OriginalMesh = filter.sharedMesh;

        WorkingMesh = Instantiate(filter.sharedMesh) as Mesh;
        filter.sharedMesh = WorkingMesh;


        ArrayList ActiveVertex = new ArrayList();

        for (int i = 0; i < WorkingMesh.vertices.Length; i++){
            if ((OriginalMesh.colors[i].r + OriginalMesh.colors[i].g + OriginalMesh.colors[i].b) != 3) ActiveVertex.Add(i);
        }

        ColorIntensity = new float[ActiveVertex.Count];
        vr = new VertexRubber[ActiveVertex.Count];

        for (int i = 0; i < ActiveVertex.Count; i++)
        {
            int ref_index = (int)ActiveVertex[i];
            ColorIntensity[i] = (1 - ((OriginalMesh.colors[ref_index].r + OriginalMesh.colors[ref_index].g + OriginalMesh.colors[ref_index].b) / 3)) * EffectIntensity;
            vr[i] = new VertexRubber(transform.TransformPoint(OriginalMesh.vertices[ref_index]), mass, gravity, stiffness, damping);
            vr[i].indexId = ref_index;
        }
        
        V3_WorkingMesh = OriginalMesh.vertices;

    }


    void Update()
    {
        
        checkPreset();

        if ((this.transform.position != last_world_position || this.transform.rotation != last_world_rotation) && sleeping)
        {
            for (int i = 0; i < vr.Length; i++)
            {
                vr[i].v_sleeping = false;
            }
            sleeping = false;
            Debug.Log(«resetando»);
        }

        if (!sleeping)
        {

            V3_WorkingMesh = OriginalMesh.vertices;
            int total = vr.Length;
            int v_sleeping_counter = 0;
            for (int i = 0; i < vr.Length; i++)
            {

                if (vr[i].v_sleeping)
                {
                    v_sleeping_counter++;
                }
                
                Vector3 v3_target = transform.TransformPoint(V3_WorkingMesh[vr[i].indexId]);

                vr[i].v_gravity = gravity;
                vr[i].v_mass = mass;
                vr[i].v_stiffness = stiffness;
                vr[i].v_damping = damping;

                vr[i].update(v3_target);

                v3_target = transform.InverseTransformPoint(vr[i].pos);

                V3_WorkingMesh[vr[i].indexId] = Vector3.Lerp(V3_WorkingMesh[vr[i].indexId], v3_target, ColorIntensity[i] * EffectIntensity);

            }

            WorkingMesh.vertices = V3_WorkingMesh;
            WorkingMesh.RecalculateBounds();

            if (this.transform.position == last_world_position && this.transform.rotation == last_world_rotation && v_sleeping_counter == vr.Length)
            {
                sleeping = true;
            }
            else
            {
                last_world_position = this.transform.position;
                last_world_rotation = this.transform.rotation;
            }
            
        }

        if (sleeping)
        {
            WorkingMesh.vertices = V3_WorkingMesh;
            WorkingMesh.RecalculateBounds();
        }


    }

    void checkPreset() {
            
        switch (Presets)
        {
            case RubberType.HardRubber:
                gravity = 0f;
                mass = 8f;
                stiffness = 0.5f;
                damping = 0.9f;
                EffectIntensity = 0.5f;
                break;
            case RubberType.Jelly:
                gravity = 0f;
                mass = 1f;
                stiffness = 0.95f;
                damping = 0.95f;
                EffectIntensity = 1f;
                break;
            case RubberType.RubberDuck:
                gravity = 0f;
                mass = 2f;
                stiffness = 0.5f;
                damping = 0.85f;
                EffectIntensity = 1f;
                break;
            case RubberType.SoftLatex:
                gravity = 1f;
                mass = 0.9f;
                stiffness = 0.3f;
                damping = 0.25f;
                EffectIntensity = 1f;
                break;
        }
    }
}


Cкриншоты:
СИМУЛЯЦИЯ РЕЗИНОВЫХ ОБЪЕКТОВ Unity 3d
С сайта (1.3 Kb)
Примечание:
Статус:
V Проверено
Фаил скачан:
218 раз
Размер:
1.3 Kb
Всего комментариев: 0
avatar

Ресурс Bas-game-zona.my1.ru © поможет скачать вам полезную информацию 2009-2017.

Любой файл будет удален по требованию правообладателя. Хостинг от uCoz