Paint in 3D
Paint in 3D用於在遊戲內和編輯器裡繪製所有物體。所有功能已經過深度優化,在WebGL、移動端、VR 以及更多平臺用起來都非常好用!
它支援標準管線,以及 LWRP、HDRP 和 URP。通過使用GPU 加速,你的物體將以難以置信的速度被繪製。程式碼還經過深度優化來防止GC,和將所有繪製操作一起批次完成。
跟貼圖系統不同,它是一個紋理繪製解決方案。這意味著你可以繪製你的物體上百萬次,還是無幀率丟失,讓你創作難以想象的遊戲。
它在Unity應用商店上的售價是60美元,地址:https://assetstore.unity.com/packages/tools/painting/paint-in-3d-26286。
Photon
Photon中文翻譯為“光子”,為有著15年伺服器後端開發經驗的德國Exit Games公司開發的高效,穩定,可擴充的網路引擎。為目前世界上使用者最廣泛,支援遊戲型別最多的專業網路引擎之一,也是Unity應用商店裡使用者評價最高的網路元件。
世界多個知名遊戲公司和工作室選用Photon作為其產品的網路支援引擎,其中包括WB華納,Codemaster, 2K, Glu, 微軟遊戲工作室,史克威爾艾尼克斯,百代南夢宮,SandBox,雨神電競等知名企業,也有許多工作室和新創企業正在瞭解和試用Photon之中。
它在Unity應用商店上有一個免費應用,地址:https://assetstore.unity.com/packages/tools/network/pun-2-free-119922。
當然,Photon需要註冊賬號、建立應用等操作才能使用,還不瞭解的同學可以去官方網站查閱相關資料。
溫馨提示:Photon的國外伺服器在國內使用比較卡,所以最好去中國官網申請國內的伺服器,申請地址:https://vibrantlink.com/chinacloudapply/。
下面正式開始。
建立工程
使用Unity Hub建立一個3D專案,然後分別引入Paint in 3D和Photon Unity Networking 2,如下圖:
溫馨提示:在引入Photon Unity Networking 2後,記得配置AppId。
建立簡易畫板
為了方便演示,我們建立一個Quad作為畫板,然後為其新增P3dPaintable、P3dMaterialCloner和P3dPaintableTexture元件,使用它們的預設配置即可,如下圖:
然後,建立一個空的GameObject命名為OneMorePaint
,然後向OneMorePaint
新增P3dPaintSphere元件,修改P3dPaintSphere元件的Color為紅色,其他配置保持預設不變,如下圖:
再向OneMorePaint
新增P3dHitScreen元件,勾選上P3dHitScreen元件的ConnectHits,其他配置保持預設不變,如下圖:
這時候,建立簡易畫板就做好了,執行以後就可以畫畫了,如下圖:
只不過,還是個單機版,我們加上實時線上功能。
連線PUN2伺服器
建立一個C#指令碼命名為Launcher
,再建立一個空的GameObject命名為LauncherGameObject
,把C#指令碼Launcher
新增到LauncherGameObject
中。
編輯C#指令碼Launcher
為如下內容:
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
namespace One.More
{
public class Launcher : MonoBehaviourPunCallbacks
{
#region Private Fields
/// <summary>
/// This client's version number. Users are separated from each other by gameVersion (which allows you to make breaking changes).
/// </summary>
string gameVersion = "1";
/// <summary>
/// Keep track of the current process. Since connection is asynchronous and is based on several callbacks from Photon,
/// we need to keep track of this to properly adjust the behavior when we receive call back by Photon.
/// Typically this is used for the OnConnectedToMaster() callback.
/// </summary>
bool isConnecting;
#endregion
void Start()
{
this.Connect();
}
#region MonoBehaviourPunCallbacks Callbacks
public override void OnConnectedToMaster()
{
Debug.Log("PUN Basics Tutorial/Launcher: OnConnectedToMaster() was called by PUN");
// we don't want to do anything if we are not attempting to join a room.
// this case where isConnecting is false is typically when you lost or quit the game, when this level is loaded, OnConnectedToMaster will be called, in that case
// we don't want to do anything.
if (isConnecting)
{
// #Critical: The first we try to do is to join a potential existing room. If there is, good, else, we'll be called back with OnJoinRandomFailed()
PhotonNetwork.JoinRandomRoom();
isConnecting = false;
}
}
public override void OnDisconnected(DisconnectCause cause)
{
Debug.LogWarningFormat("PUN Basics Tutorial/Launcher: OnDisconnected() was called by PUN with reason {0}", cause);
isConnecting = false;
}
public override void OnJoinRandomFailed(short returnCode, string message)
{
Debug.Log("PUN Basics Tutorial/Launcher:OnJoinRandomFailed() was called by PUN. No random room available, so we create one.\nCalling: PhotonNetwork.CreateRoom");
// #Critical: we failed to join a random room, maybe none exists or they are all full. No worries, we create a new room.
PhotonNetwork.CreateRoom(null, new RoomOptions());
}
public override void OnJoinedRoom()
{
Debug.Log("PUN Basics Tutorial/Launcher: OnJoinedRoom() called by PUN. Now this client is in a room.");
}
#endregion
#region Public Methods
/// <summary>
/// Start the connection process.
/// - If already connected, we attempt joining a random room
/// - if not yet connected, Connect this application instance to Photon Cloud Network
/// </summary>
public void Connect()
{
// we check if we are connected or not, we join if we are , else we initiate the connection to the server.
if (PhotonNetwork.IsConnected)
{
// #Critical we need at this point to attempt joining a Random Room. If it fails, we'll get notified in OnJoinRandomFailed() and we'll create one.
PhotonNetwork.JoinRandomRoom();
}
else
{
// #Critical, we must first and foremost connect to Photon Online Server.
isConnecting = PhotonNetwork.ConnectUsingSettings();
PhotonNetwork.GameVersion = gameVersion;
}
}
#endregion
}
}
這時候,就可以連線到連線PUN2伺服器了,執行以後我們可以看到如下日誌:
實時線上同步
向之前建立的OneMorePaint
新增PhotonView元件,使用預設配置即可,如下圖:
建立一個C#指令碼命名為OnlinePainting
,把C#指令碼OnlinePainting
新增到OneMorePaint
中。
編輯C#指令碼OnlinePainting
為如下內容:
using PaintIn3D;
using Photon.Pun;
using UnityEngine;
namespace One.More
{
public class OnlinePainting : MonoBehaviour, IHitPoint, IHitLine
{
private PhotonView photonView;
private P3dPaintSphere paintSphere;
void Start()
{
this.photonView = this.GetComponent<PhotonView>();
this.paintSphere = this.GetComponent<P3dPaintSphere>();
}
public void HandleHitPoint(bool preview, int priority, float pressure, int seed, Vector3 position, Quaternion rotation)
{
if (preview)
{
return;
}
if (this.photonView == null)
{
Debug.LogError("PhotonView is not found.");
return;
}
this.photonView.RPC("HandleHitPointRpc", RpcTarget.Others, preview, priority, pressure, seed, position, rotation);
}
public void HandleHitLine(bool preview, int priority, float pressure, int seed, Vector3 position, Vector3 endPosition, Quaternion rotation, bool clip)
{
if (preview)
{
return;
}
if (this.photonView == null)
{
Debug.LogError("PhotonView is not found.");
return;
}
this.photonView.RPC("HandleHitLinetRpc", RpcTarget.Others, preview, priority, pressure, seed, position, endPosition, rotation, clip);
}
[PunRPC]
public void HandleHitPointRpc(bool preview, int priority, float pressure, int seed, Vector3 position, Quaternion rotation)
{
if (this.paintSphere == null)
{
Debug.LogError("P3dPaintSphere is not found.");
return;
}
this.paintSphere.HandleHitPoint(preview, priority, pressure, seed, position, rotation);
}
[PunRPC]
public void HandleHitLinetRpc(bool preview, int priority, float pressure, int seed, Vector3 position, Vector3 endPosition, Quaternion rotation, bool clip)
{
if (this.paintSphere == null)
{
Debug.LogError("P3dPaintSphere is not found.");
return;
}
this.paintSphere.HandleHitLine(preview, priority, pressure, seed, position, endPosition, rotation, clip);
}
}
}
線上塗鴉畫板就製作完成了,我們看看執行效果怎麼樣?
執行效果
構建以後,同時啟動兩個客戶端,效果如下:
當然,這只是簡單的線上塗鴉畫板,你還可以再此基礎上新增更豐富的功能,比如:修改畫筆顏色、修改畫筆大小等等。
最後,謝謝你這麼帥,還給我點贊和關注。