修改PaintIn3D插件源码
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. 最终效果