示例#1
0
    void OnEnable()
    {
        tentacle = (SoxAtkTentacle)target;

        // 프로젝트 창에서 선택한 프리팹을 버전체크하면 문제가 발생한다. Selection.transforms.Length가 0이면 Project View 라는 뜻
        if (Selection.transforms.Length > 0 && Application.isPlaying && tentacle.gameObject.activeInHierarchy && tentacle.enabled)
        {
            tentacle.MyValidate();
        }
    }
示例#2
0
    public void RemoveMixedTentacle()
    {
        if (m_tentacle != null)
        {
            GameObject.DestroyImmediate(m_tentacle.gameObject);
        }

        m_soxAtkTentacle   = null;
        m_tree[0].m_ifHead = true;

        if (m_soxAtkTentacle != null)
        {
            if (m_soxAtkTentacle.m_jiggleboneHeads.Contains(m_tree[0]) == true)
            {
                m_soxAtkTentacle.m_jiggleboneHeads.Remove(m_tree[0]);
            }
        }
    }
示例#3
0
    // 텐터클과 믹스되는 텐터클 본 생성, 텐터클 본 리턴
    public Transform SetMixedTentacle(SoxAtkTentacle soxAtkTentacle)
    {
        if (m_tentacle == null)
        {
            InitializeTentacle();
        }

        m_soxAtkTentacle = soxAtkTentacle;

        // 최상위 헤드의 역할을 봉인하고 텐터클에게 위임한다. (텐터클이 무조건 먼저 발동되어야함)
        m_tree[0].m_ifHead = false;

        if (soxAtkTentacle.m_jiggleboneHeads.Contains(m_tree[0]) == false)
        {
            soxAtkTentacle.m_jiggleboneHeads.Add(m_tree[0]);
        }

        return(m_tentacle);
    }
示例#4
0
    public override void OnInspectorGUI()
    {
        tentacle = (SoxAtkTentacle)target;

        // GUI레이아웃 시작=======================================================
        Undo.RecordObject(target, "Tentacle Changed Settings");
        EditorGUI.BeginChangeCheck();

        GUILayout.BeginHorizontal();
        if (GUILayout.Button("Auto register nodes"))
        {
            AutoRegisterNodes();
        }

        if (GUILayout.Button("Clear nodes"))
        {
            ClearNodes();
        }
        GUILayout.EndHorizontal();

        tentacle.m_animated = EditorGUILayout.Toggle(new GUIContent("Animated", "This should only be used if Animation is active. Even if it is not Animation, it uses all the changes that operate on Update(). Please use it only when necessary, as it may affect performance."), tentacle.m_animated);
        if (tentacle.m_animated)
        {
            GUI.enabled = false;
        }
        tentacle.m_keepInitialRotation = EditorGUILayout.Toggle("Keep Initial Rotation", tentacle.m_keepInitialRotation);
        GUI.enabled = true;

        DrawDefaultInspector();

        if (EditorGUI.EndChangeCheck())
        {
            // 프로젝트 창에서 선택한 프리팹을 버전체크하면 문제가 발생한다. Selection.transforms.Length가 0이면 Project View 라는 뜻
            if (Selection.transforms.Length > 0 && Application.isPlaying && tentacle.gameObject.activeInHierarchy && tentacle.enabled)
            {
                tentacle.MyValidate();
            }
        }
        Undo.FlushUndoRecordObjects();

#if UNITY_EDITOR
        // 프로젝트 창에서 Bake 관련 작업을 하면 문제가 된다.. Selection.transforms.Length가 0이면 Project View
        if (Selection.transforms.Length == 0)
        {
            return;
        }

        // 여기부터는 에디터 전용 기능.
        if (Application.isPlaying)
        {
            GUI.enabled = false;
        }

        EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
        GUILayout.BeginHorizontal();
        if (GUILayout.Button("Bake Animation"))
        {
            BakeAnimation();
        }

        if (GUILayout.Button("Auto Tangent"))
        {
            AutoTangent();
        }

        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal();
        tentacle.m_bakeTime    = EditorGUILayout.FloatField("Bake Time", tentacle.m_bakeTime);
        tentacle.m_bakeTime    = Mathf.Max(0f, tentacle.m_bakeTime);
        tentacle.m_bakeSamples = EditorGUILayout.IntField("Sample Rate", tentacle.m_bakeSamples);
        tentacle.m_bakeSamples = Mathf.Max(1, tentacle.m_bakeSamples);
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal();
        tentacle.m_bakeLoopTime        = EditorGUILayout.ToggleLeft("Loop Time", tentacle.m_bakeLoopTime);
        tentacle.m_bakeDisableTentacle = EditorGUILayout.ToggleLeft("Disable Tentacle after Bake", tentacle.m_bakeDisableTentacle);
        GUILayout.EndHorizontal();

        if (tentacle.wavesets.Length > 0)
        {
            string loopInfo = "";
            for (int i = 0; i < tentacle.wavesets.Length; i++)
            {
                float loopTime = (Mathf.PI * 2f) / tentacle.wavesets[i].m_speed;
                loopTime = Mathf.Abs(loopTime);
                float loopFrame = loopTime * tentacle.m_bakeSamples;
                if (i >= 1)
                {
                    loopInfo += "\n";
                }
                loopInfo += "Element " + i.ToString() + " Looping > " + loopTime.ToString() + " sec. " + loopFrame.ToString() + " frames";
            }
            EditorGUILayout.HelpBox(loopInfo, MessageType.None);
        }

        GUILayout.BeginHorizontal();
        m_loopFrame = EditorGUILayout.IntField(new GUIContent("Looping Calculator", "The number of frames you want to loop."), m_loopFrame);
        m_loopFrame = Mathf.Max(1, m_loopFrame);
        m_loopSpeed = (Mathf.PI * 2f) / ((float)m_loopFrame / (float)tentacle.m_bakeSamples);
        EditorGUILayout.FloatField(m_loopSpeed);
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal();
        GUILayout.Label("Information ▶");
        if (GUILayout.Button(new GUIContent("Is the bake wrong?", "Information about when the result of the Bake differs from the execution result.")))
        {
            EditorUtility.DisplayDialog("Is the bake wrong?", "Tentacle calculated in real time is calculated by Quaternion method and can be expressed at any angle. However, bake results with Keyframe are applied as Euler, so extreme rotations can work abnormally. In addition, since the Euler method is highly influenced by the direction of the parent axis, the initial rotation value of each node should be minimized.", "OK");
        }

        if (GUILayout.Button(new GUIContent("이상하게 구워지면?", "Bake 결과가 실행했을 때와 다른가요?")))
        {
            EditorUtility.DisplayDialog("이상하게 구워지면?", "실시간으로 계산되는 Tentacle은 Quaternion 방식으로 계산되어서 어떤 각도라도 표현이 가능합니다. 하지만 Keyframe으로 Bake한 결과는 Euler로 적용되기때문에 과격한 회전은 비정상적으로 작동할 수 있습니다. 또한 Euler 방식은 부모의 축 방향에 영향을 많이 받기때문에, 각 노드들의 초기 회전값을 최소화 해야합니다.", "OK");
        }
        GUILayout.EndHorizontal();

        EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
        if (GUILayout.Button(new GUIContent("Optimize Keyframes", "Optimize Keyframes works under the assumption that Auto Tangents are applied. If you manually edit the tangent and apply optimization to the edited curve, you will get the wrong result.")))
        {
            OptimizeKeyframes(tentacle.m_optimizeThresholdTangent);
        }
        GUILayout.BeginHorizontal();
        tentacle.m_optimizeThresholdTangent         = EditorGUILayout.FloatField(new GUIContent("Optimize Threshold", "Compares tangents to optimize keyframes. It is used after multiplying this value with the Strength value of each node."), tentacle.m_optimizeThresholdTangent);
        tentacle.m_optimizeThresholdTangent         = Mathf.Max(0f, tentacle.m_optimizeThresholdTangent);
        tentacle.m_optimizeThresholdDefaultStrength = EditorGUILayout.FloatField(new GUIContent("Default Strength", "Default Strength of Optimize Threshold. Strength value to use when optimizing keyframes that are not in Nodes. The Optimize Threshold value is applied considering the strength of each node."), tentacle.m_optimizeThresholdDefaultStrength);
        tentacle.m_optimizeThresholdDefaultStrength = Mathf.Max(0f, tentacle.m_optimizeThresholdDefaultStrength);
        GUILayout.EndHorizontal();

        tentacle.m_optimizeThresholdStrengthRate = EditorGUILayout.Slider(new GUIContent("Applying Strength Rate", "How much to multiply the Threshold value and Strength. If this value is 0, the threshold is not multiplied by Strength."), tentacle.m_optimizeThresholdStrengthRate, 0f, 1f);

        GUI.enabled = true;
#endif
        // GUI레이아웃 끝========================================================
    } // end of OnInspectorGUI()