Debug Pose

VR/Oculus Integration 2023. 12. 10. 23:18
반응형

 

Active State Debug Tree UI 컴포넌트에서 노드를 만든다 

 

 

 

/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 * All rights reserved.
 *
 * Licensed under the Oculus SDK License Agreement (the "License");
 * you may not use the Oculus SDK except in compliance with the License,
 * which is provided at the time of installation or download, or which
 * otherwise accompanies this software in either electronic or hard copy form.
 *
 * You may obtain a copy of the License at
 *
 * https://developer.oculus.com/licenses/oculussdk/
 *
 * Unless required by applicable law or agreed to in writing, the Oculus SDK
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

using Oculus.Interaction.DebugTree;
using UnityEngine;

namespace Oculus.Interaction.PoseDetection.Debug
{
    public class ActiveStateDebugTreeUI : DebugTreeUI<IActiveState>
    {
        [Tooltip("The IActiveState to debug.")]
        [SerializeField, Interface(typeof(IActiveState))]
        private UnityEngine.Object _activeState;

        [Tooltip("The node prefab which will be used to build the visual tree.")]
        [SerializeField, Interface(typeof(INodeUI<IActiveState>))]
        private UnityEngine.Component _nodePrefab;

        protected override IActiveState Value
        {
            get => _activeState as IActiveState;
        }

        protected override INodeUI<IActiveState> NodePrefab
        {
            get => _nodePrefab as INodeUI<IActiveState>;
        }

        protected override DebugTree<IActiveState> InstantiateTree(IActiveState value)
        {
            return new ActiveStateDebugTree(value);
        }
        protected override string TitleForValue(IActiveState value)
        {
            Object obj = value as Object;
            return obj != null ? obj.name : "";
        }

    }
}

 

/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 * All rights reserved.
 *
 * Licensed under the Oculus SDK License Agreement (the "License");
 * you may not use the Oculus SDK except in compliance with the License,
 * which is provided at the time of installation or download, or which
 * otherwise accompanies this software in either electronic or hard copy form.
 *
 * You may obtain a copy of the License at
 *
 * https://developer.oculus.com/licenses/oculussdk/
 *
 * Unless required by applicable law or agreed to in writing, the Oculus SDK
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

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

namespace Oculus.Interaction.DebugTree
{
    public interface INodeUI<TLeaf>
        where TLeaf : class
    {
        RectTransform ChildArea { get; }
        void Bind(ITreeNode<TLeaf> node, bool isRoot, bool isDuplicate);
    }

    public abstract class DebugTreeUI<TLeaf> : MonoBehaviour
        where TLeaf : class
    {
        [Tooltip("Node prefabs will be instantiated inside of this content area.")]
        [SerializeField]
        private RectTransform _contentArea;

        [Tooltip("This title text will display the GameObject name of the IActiveState.")]
        [SerializeField, Optional]
        private TMP_Text _title;

        [Tooltip("If true, the tree UI will be built on Start.")]
        [SerializeField]
        private bool _buildTreeOnStart;

        protected abstract TLeaf Value { get; }
        protected abstract INodeUI<TLeaf> NodePrefab { get; }

        private DebugTree<TLeaf> _tree;

        private Dictionary<ITreeNode<TLeaf>, INodeUI<TLeaf>> _nodeToUI
            = new Dictionary<ITreeNode<TLeaf>, INodeUI<TLeaf>>();

        protected virtual void Start()
        {
            this.AssertField(Value, nameof(Value));
            this.AssertField(NodePrefab, nameof(NodePrefab));
            this.AssertField(_contentArea, nameof(_contentArea));

            if (_buildTreeOnStart)
            {
                BuildTree();
            }
        }

        public void BuildTree()
        {
            _nodeToUI.Clear();
            ClearContentArea();
            SetTitleText();
            _tree = InstantiateTree(Value);
            BuildTreeRecursive(_contentArea, _tree.GetRootNode(), true);
        }

        private void BuildTreeRecursive(
            RectTransform parent, ITreeNode<TLeaf> node, bool isRoot)
        {
            INodeUI<TLeaf> nodeUI = Instantiate(NodePrefab as Object, parent) as INodeUI<TLeaf>;

            bool isDuplicate = _nodeToUI.ContainsKey(node);
            nodeUI.Bind(node, isRoot, isDuplicate);

            if (!isDuplicate)
            {
                _nodeToUI.Add(node, nodeUI);
                foreach (var child in node.Children)
                {
                    BuildTreeRecursive(nodeUI.ChildArea, child, false);
                }
            }
        }

        private void ClearContentArea()
        {
            for (int i = 0; i < _contentArea.childCount; ++i)
            {
                Transform child = _contentArea.GetChild(i);
                if (child != null && child.TryGetComponent<INodeUI<TLeaf>>(out _))
                {
                    Destroy(child.gameObject);
                }
            }
        }

        private void SetTitleText()
        {
            if (_title != null)
            {
                _title.text = TitleForValue(Value);
            }
        }

        protected abstract DebugTree<TLeaf> InstantiateTree(TLeaf value);
        protected abstract string TitleForValue(TLeaf value);

#if UNITY_EDITOR
        private void OnValidate()
        {
            SetTitleText();
        }
#endif
    }
}

 

 

 

Children에 붙이면 옆으로 계속 늘어남 이건 나중에 스킬트리 같은데 써먹으면 될듯 

 

 


 

암튼 우리가 집중해서 봐야 할것은 

빨간색 박스임

 

 

 

 

결국 포즈를 감지 해서 녹색으로 바꾸는 역할을 누가 하는가인데 

 

 

감지는 여기서 하고

 

 

 

 

그걸 참조 하고 

 

 

 

 

 

 

 

코드는 어디이찌

 

/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 * All rights reserved.
 *
 * Licensed under the Oculus SDK License Agreement (the "License");
 * you may not use the Oculus SDK except in compliance with the License,
 * which is provided at the time of installation or download, or which
 * otherwise accompanies this software in either electronic or hard copy form.
 *
 * You may obtain a copy of the License at
 *
 * https://developer.oculus.com/licenses/oculussdk/
 *
 * Unless required by applicable law or agreed to in writing, the Oculus SDK
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

using UnityEngine;
using TMPro;
using UnityEngine.UI;
using UnityEngine.Assertions;
using Oculus.Interaction.DebugTree;

namespace Oculus.Interaction.PoseDetection.Debug
{
    public class ActiveStateNodeUIHorizontal : MonoBehaviour, INodeUI<IActiveState>
    {
        [SerializeField]
        private RectTransform _childArea;

        [SerializeField]
        private RectTransform _connectingLine;

        [SerializeField]
        private TextMeshProUGUI _label;

        [SerializeField]
        private Image _activeImage;

        [SerializeField]
        private Color _activeColor = Color.green;

        [SerializeField]
        private Color _inactiveColor = Color.red;

        private const string OBJNAME_FORMAT = "<color=#dddddd><size=85%>{0}</size></color>";

        public RectTransform ChildArea => _childArea;

        private ITreeNode<IActiveState> _boundNode;
        private bool _isRoot = false;
        private bool _isDuplicate = false;

        public void Bind(ITreeNode<IActiveState> node, bool isRoot, bool isDuplicate)
        {
            Assert.IsNotNull(node);

            _isRoot = isRoot;
            _isDuplicate = isDuplicate;
            _boundNode = node;
            _label.text = GetLabelText(node);
        }

        protected virtual void Start()
        {
            this.AssertField(_childArea, nameof(_childArea));
            this.AssertField(_connectingLine, nameof(_connectingLine));
            this.AssertField(_activeImage, nameof(_activeImage));
            this.AssertField(_label, nameof(_label));
        }

        protected virtual void Update()
        {
            _activeImage.color = _boundNode.Value.Active ? _activeColor : _inactiveColor;
            _childArea.gameObject.SetActive(_childArea.childCount > 0);
            _connectingLine.gameObject.SetActive(!_isRoot);
        }

        private string GetLabelText(ITreeNode<IActiveState> node)
        {
            string label = _isDuplicate ? "<i>" : "";
            if (node.Value is UnityEngine.Object obj)
            {
                label += obj.name + System.Environment.NewLine;
            }
            label += string.Format(OBJNAME_FORMAT, node.Value.GetType().Name);
            return label;
        }
    }
}

 

 

state의 Value에서 알수 있나보네 

/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 * All rights reserved.
 *
 * Licensed under the Oculus SDK License Agreement (the "License");
 * you may not use the Oculus SDK except in compliance with the License,
 * which is provided at the time of installation or download, or which
 * otherwise accompanies this software in either electronic or hard copy form.
 *
 * You may obtain a copy of the License at
 *
 * https://developer.oculus.com/licenses/oculussdk/
 *
 * Unless required by applicable law or agreed to in writing, the Oculus SDK
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace Oculus.Interaction
{
    public interface IActiveState
    {
        bool Active { get; }
    }
}

 

 

 

 

 

그럼 정적으로 UI를 다시 구현해본다 

 

빈오브젝트를 생성하고 

 

위치와 레이어를 설정하고

 

Canvas 컴포넌트를 부착하고 

 

위치와 스케일을 조정 

 

자식으로 Image를 만들고 

 

 

 

ThumbsUpDebugRight를 선택하고 자식으로 Image 3개를 만든다 

 

이름을 이렇게 바꿔주고

 

 

같은 이름의 스크립트를 만들고 

 

 

각 오브젝트에 알맞게 컴포넌트를 추가 한다 

 

 

using System;
using System.Collections;
using System.Collections.Generic;
using Oculus.Interaction;
using UnityEngine;
using UnityEngine.UI;

public class DebugPoseRecocnizer : MonoBehaviour
{

    [SerializeField] private ActiveStateGroup activeStateGroup;
    private Image img;

    private void Awake()
    {
        this.img = this.GetComponent<Image>();
    }

    private void Update()
    {
        if (this.activeStateGroup.Active)
        {
            this.img.color = Color.green;
        }
        else
        {
            this.img.color = Color.red;
        }
    }
}

 

잘 동작 한다

 


 

 

DebugShapeRecognizer 

using System.Collections;
using System.Collections.Generic;
using Oculus.Interaction;
using Oculus.Interaction.PoseDetection;
using UnityEngine;
using UnityEngine.UI;
public class DebugShapeRecognizer : MonoBehaviour
{

    [SerializeField] private ShapeRecognizerActiveState activeState;
    private Image img;

    private void Awake()
    {
        this.img = this.GetComponent<Image>();
    }

    private void Start()
    {
        
    }

    private void Update()
    {
        if (this.activeState.Active)
        {
            this.img.color = Color.green;
        }
        else
        {
            this.img.color = Color.red;
        }
    }
}

 

 

 

 

 


 

DebugTransformRecognizer

using System.Collections;
using System.Collections.Generic;
using Oculus.Interaction.PoseDetection;
using UnityEngine;
using UnityEngine.UI;
public class DebugTransformRecognizer : MonoBehaviour
{
    [SerializeField] private TransformRecognizerActiveState activeState;
    private Image img;

    private void Awake()
    {
        this.img = this.GetComponent<Image>();
    }

    private void Start()
    {
        
    }

    private void Update()
    {
        if (this.activeState.Active)
        {
            this.img.color = Color.green;
        }
        else
        {
            this.img.color = Color.red;
        }
    }
}

 

 

 

잘 동작 한다 

 

 

 

 

 

 


다음은 포즈 감지  부분 

 

 

 

 

처음부터 만들어 보기 

빈오브젝트를 만들고 

 

  • Hand Ref 
  • Selector Unity Event Wrapper 
  • Active State Selector 
  • Active State Group
  • Shape Recognizer Active State 
  • Transform Recognizer Active State 

컴포넌트를 부착 한다 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


참고 

https://developer.oculus.com/documentation/unity/unity-isdk-building-hand-pose-recognizer/

https://developer.oculus.com/documentation/unity/unity-isdk-active-state/

https://developer.oculus.com/documentation/unity/unity-isdk-use-active-state/

반응형

'VR > Oculus Integration' 카테고리의 다른 글

Oculus Integration SDK (R&D 리스트)  (0) 2023.12.11
Use Active State  (0) 2023.12.11
Hand Pose Detection  (0) 2023.12.10
Controller Ray Visual  (0) 2023.12.08
Create a Curved UI  (0) 2023.12.08
: