[Unity3D]修改PaintIn3D插件源码以便用于VR

10 篇文章 0 订阅
3 篇文章 0 订阅

1. 导入PaintIn3D插件和SteamVR

在这里插入图片描述
在这里插入图片描述

2. 修改PaintIn3D插件源码

2.1 修改P3dHitScreen.cs

打开P3dHitScreen.cs文件,该脚本主要用于射线检测和按键判断,可以在场景的Tools子对象中打开该脚本
在这里插入图片描述
在这里插入图片描述
找到PaintAt方法后多复制粘贴一次该方法,用于重载
修改参数screenPosition的变量类型,由Vector3改为Transform
注释原本的var ray = camera.ScreenPointToRay(screenPosition);,并重新编写Ray变量
Ray ray = new Ray(screenPosition.position,screenPosition.forward);

private void PaintAt(Link link, Vector3 screenPosition, bool preview, float pressure, object owner, Transform _transform)
{
	// Debug.Log(screenPosition);

	if (link != null)
	{
		link.Record(screenPosition);
	}

	var camera = P3dHelper.GetCamera(_camera);

	if (camera != null)
	{
		if (touchOffset != 0.0f && P3dInputManager.TouchCount > 0)
		{
			screenPosition.y += touchOffset * P3dInputManager.ScaleFactor;
		}


		// var ray = camera.ScreenPointToRay(screenPosition);
		Ray ray = new Ray(screenPosition,_transform.forward);
		var hit = default(RaycastHit);

		if (Physics.Raycast(ray, out hit, float.PositiveInfinity, layers) == true)
		{
			Debug.DrawLine(ray.origin, hit.point, Color.green);
			var finalPosition = hit.point + hit.normal * offset;
			var finalRotation = Quaternion.identity;
	
	
			switch (rotateTo)
			{
				case RotationType.Normal:
				{
					var finalNormal = default(Vector3);
	
					switch (normalDirection)
					{
						case DirectionType.HitNormal: finalNormal = hit.normal; break;
						case DirectionType.RayDirection: finalNormal = -ray.direction; break;
						case DirectionType.CameraDirection: finalNormal = -camera.transform.forward; break;
					}
	
					var finalUp = default(Vector3);
	
					switch (normalRelativeTo)
					{
						case RelativeType.WorldUp: finalUp = Vector3.up; break;
						case RelativeType.CameraUp: finalUp = camera.transform.up; break;
					}
	
					finalRotation = Quaternion.LookRotation(-finalNormal, finalUp);
				}
				break;
				case RotationType.World: finalRotation = Quaternion.identity; break;
				case RotationType.ThisRotation: finalRotation = transform.rotation; break;
				case RotationType.ThisLocalRotation: finalRotation = transform.localRotation; break;
				case RotationType.CustomRotation: 
					if (customTransform != null) finalRotation = customTransform.rotation; 
					break;
				case RotationType.CustomLocalRotation: 
					if (customTransform != null) finalRotation = customTransform.localRotation;
					break;
			}
	
			switch (draw)
			{
				case DrawType.PointsIn3D:
				case DrawType.PointsIn3DFilled:
				{
					SubmitPoint(preview, priority, pressure, finalPosition, finalRotation, owner);
				}
					break;
	
				case DrawType.PointsOnUV:
				{
					hitCache.InvokeCoord(gameObject, preview, priority, pressure, new P3dHit(hit), finalRotation);
				}
					break;
	
				case DrawType.TrianglesIn3D:
				{
					hitCache.InvokeTriangle(gameObject, preview, priority, pressure, hit, finalRotation);
				}
					break;
			}
			return;
		}
	}

	BreakHits(owner);
}

在P3dHitScreen.cs文件中声明一个新的变量RayPosition,用于传递手柄位置

[System.NonSerialized]
private List<Link> links = new List<Link>();

[System.NonSerialized]
public P3dInputManager inputManager = new P3dInputManager();

public Transform RayPosition;

查找P3dHitScreen.cs文件中所有有引用到PaintAt方法(原方法,不是后面重载的)的位置,修改第二个参数变量为RayPosition.position,并加入最后一个参数Transform _transform的实参RayPosition

if (showPreview == true)
{
	if (P3dInputManager.MouseExists == true && inputManager.Fingers.Count == 0 && 	P3dInputManager.PointOverGui(P3dInputManager.MousePosition) == false)
	{
		// PaintAt(null, P3dInputManager.MousePosition, true, 1.0f, this);
		PaintAt(null, RayPosition.position, true, 1.0f, this, RayPosition);
    }
    else
    {
         BreakHits(this);
    }
}

一共有五处需要进行如上修改
在这里插入图片描述

2.2 修改P3dInputManager.cs

打开P3dInputManager.cs文件,找到Finger类,将所有的Vector2变量类型改为Vector3
在这里插入图片描述
找到 GetAveragePosition,GetAveragePullScaled和GetAverageDeltaScaled,Hermite方法,同样把返回值改为Vector3
在这里插入图片描述
在这里插入图片描述

找到AddFinger方法,修改第二个参数类型为Vector3
在这里插入图片描述
如果在修改过程中出现变量类型报错信息,修改对应的变量类型即可

声明四个变量
前三个用于判断手柄按键,第四个用于传递射线发射点

public bool IsPressedForSteamVR;
public bool IsUpForSteamVR;
public bool IsDownForSteamVR;
public Vector3 HitPosition;

找到Update方法,修改下图处AddFinger方法参数和判断条件
在这里插入图片描述

回到P3dHitScreen.cs脚本中我们重载的PaintAt方法,添加一句
inputManager.HitPosition = screenPosition;
在这里插入图片描述
找到PaintAt方法的第二处引用,将head参数改为finger.PositionA
在这里插入图片描述

3. 传递数据

新建GameContorller.cs脚本

public class GameController : MonoBehaviour
{
    #region 单例
    
    private static GameController _instance;
    public static GameController Instance
    {
        get { return _instance; }
    }
    #endregion

    //笔刷类,储存对应数据
    public List<TouchPoint> TouchPointManager = new List<TouchPoint>();
    
    void Awake()
    {
        _instance = this;
    }

    // Start is called before the first frame update
    void Start()
    {
        #region 初始化各个玩家所拥有的笔刷贴图列表
        
        foreach (Transform _tran in TouchPointManager[0].Tool.transform)
        {
            TouchPointManager[0].Textures.Add(_tran.gameObject);
        }
        
        #endregion
    }

    // Update is called once per frame
    void Update()
    {
        #region 实时更新玩家信息
        
        //*******************************************************************************
        //玩家一
        TouchPointManager[0].Position = TouchPointManager[0].Parent.position;

        TouchPointManager[0].Texture.RayPosition = TouchPointManager[0].Parent;
        TouchPointManager[0].Texture.inputManager.IsPressedForSteamVR = SteamVR_Actions._default.GrabPinch.GetStateDown(SteamVR_Input_Sources.RightHand);
        TouchPointManager[0].Texture.inputManager.IsDownForSteamVR = SteamVR_Actions._default.GrabPinch.GetStateDown(SteamVR_Input_Sources.RightHand);
        TouchPointManager[0].Texture.inputManager.IsUpForSteamVR = SteamVR_Actions._default.GrabPinch.GetStateUp(SteamVR_Input_Sources.RightHand);
        //*******************************************************************************
        
        #endregion
    }
}

[System.Serializable]
public class TouchPoint
{
    //手柄
    public Transform Parent;
    //手柄位置
    public Vector3 Position;
    //当前选择的笔刷贴图
    public P3dHitScreen Texture;
    //笔刷父对象
    public Transform Tool;
    //所有的笔刷贴图
    public List<GameObject> Textures;
}

挂载GameContorller脚本至任意对象上,拖入SteamVR相机预制体,变量如下设置
Parent对应手柄的Transform组件,Texture则是当前所使用的喷漆类型
在这里插入图片描述

4. 最终效果

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值