SwiftUI:向SceneKit场景添加SwiftUI路径

4

我试图将SwiftUI路径添加到Scenekit场景中(作为SCNShape)。

我创建了: Scenekit 视图(图片1) SwiftUI 路径(图片2)

然后我尝试根据以下方法调用SwiftUI路径: 无法使用UIBezierPath和SCNShape创建圆形

   let scnpath = ContentView()
   let shape = SCNShape(path: scnpath)
   let shapeNode = SCNNode(geometry: shape)

没有起作用,结果如下:

在此输入图片描述

import SwiftUI
import SceneKit

struct ScenekitView : UIViewRepresentable {
    let scene = SCNScene(named: "art.scnassets/ship.scn")!


    func makeUIView(context: Context) -> SCNView {
        // create and add a camera to the scene
        let cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()
        scene.rootNode.addChildNode(cameraNode)

        // add SwiftUI Path to Scenekit Scene

        let scnpath = ContentView()
        let shape = SCNShape(path: scnpath)
        let shapeNode = SCNNode(geometry: shape)

        // place the camera
        cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)


        // retrieve the SCNView
        let scnView = SCNView()
        return scnView
    }

    func updateUIView(_ scnView: SCNView, context: Context) {
        scnView.scene = scene


    }
}

#if DEBUG
struct ScenekitView_Previews : PreviewProvider {
    static var previews: some View {
        ScenekitView()
        .colorScheme(.dark)
        .previewDevice("iPad Pro (12.9-inch) (3rd generation)")
    }
}
#endif

enter image description here


import SwiftUI

struct ContentView: View {
    var body: some View {

                Path { path in
                   path.move(to: CGPoint(x: 63.5, y: 98.38))
                           path.addLine(to: CGPoint(x: 920.14, y: 0))
                           path.addLine(to: CGPoint(x: 1094.24, y: 584.81))
                           path.addLine(to: CGPoint(x: 920.14, y: 938.58))
                           path.addLine(to: CGPoint(x: 498.47, y: 1279.73))
                           path.addLine(to: CGPoint(x: 211.79, y: 938.58))
                           path.addLine(to: CGPoint(x: 617.65, y: 584.81))
                           path.addLine(to: CGPoint(x: 735.35, y: 295.94))
                           path.addLine(to: CGPoint(x: 332.02, y: 349.08))
                           path.addLine(to: CGPoint(x: 0, y: 672.25))
                           path.addLine(to: CGPoint(x: 63.5, y: 98.38))
                }
                .stroke(Color.blue, lineWidth: 3)
            }
        }

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

非常感谢任何帮助!

谢谢

3个回答

4

您的 SwiftUI 的 ContentView 是一个 View,它是一个结构体,但 SCNShape 需要 UIBezierPath,它是一个类。因此,如果您想将这些不同的概念结合起来,您需要执行以下操作:

ContentView

struct ContentView: View {
    let path =  Path { path in
       path.move(to: CGPoint(x: 63.5, y: 98.38))
               path.addLine(to: CGPoint(x: 920.14, y: 0))
               path.addLine(to: CGPoint(x: 1094.24, y: 584.81))
               path.addLine(to: CGPoint(x: 920.14, y: 938.58))
               path.addLine(to: CGPoint(x: 498.47, y: 1279.73))
               path.addLine(to: CGPoint(x: 211.79, y: 938.58))
               path.addLine(to: CGPoint(x: 617.65, y: 584.81))
               path.addLine(to: CGPoint(x: 735.35, y: 295.94))
               path.addLine(to: CGPoint(x: 332.02, y: 349.08))
               path.addLine(to: CGPoint(x: 0, y: 672.25))
               path.addLine(to: CGPoint(x: 63.5, y: 98.38))
    }

    var body: some View {
        self.path
            .stroke(Color.blue, lineWidth: 3)
    }
}

ScenekitView中。
let scnpath = ContentView().path.cgPath
let shape = SCNShape(path: UIBezierPath(cgPath: scnpath), extrusionDepth: 1.0)

非常感谢Asperi!现在它已经构建成功,所以就快完成了!:)但是我仍然没有在SceneKit场景中看到SwiftUI路径... 我尝试添加一些材料,但没有效果。你在SceneKit场景中得到了SwiftUI路径吗? - Mane Manero
我刚刚确认了SwiftUI Path不在Scenekit场景中(因此这不是附加材料的问题),因为我从视图调试器中导出了.scn文件,只有ship存在... - Mane Manero
找到了这个链接: https://www.hackingwithswift.com/quick-start/swiftui/how-to-use-uibezierpath-and-cgpath-in-swiftui但还是不行...如果你从CGPath开始而不是UIBezierPath,那么事情会更容易。这一行代码:let path = Path(bezierPath.cgPath) 变成了这样:let path = Path(yourCGPath) - Mane Manero

0

在此输入图片描述尝试这样做:

1)您没有将形状节点添加到场景中,因此您看不到它。

2)如果您对SceneKit不太熟悉,一开始不应该自己控制相机...让Scenekit为您完成,所以我删除了您的相机(因为它需要正确的位置+角度,以便您真正看到一些东西)。

3)按照asperi告诉您的那样将形状更新为您的形状-这是您可以采取的一种方法(我没有将其放在我的运行示例中,因为这对您来说太容易了 ;))

4)结果如图所示

5)我不知道您是否知道:在模拟器中,只有在点击模拟器中的“播放”按钮后才能看到scenekit视图...

struct ScenekitView : UIViewRepresentable {

    let scene = SCNScene()


    func makeUIView(context: Context) -> SCNView {

        let uiView = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
        // create and add a camera to the scene
        let cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()
  //      scene.rootNode.addChildNode(cameraNode)

        // add SwiftUI Path to Scenekit Scene

        let bezierPath = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 20, height: 20))

        let shape = SCNShape(path: bezierPath, extrusionDepth: 50)
        let shapeNode = SCNNode(geometry: shape)

        // place the camera
        cameraNode.position = SCNVector3(x: 0, y: 10, z: 25)

     //   scene.rootNode.addChildNode(cameraNode)
        scene.rootNode.addChildNode(shapeNode)

        // retrieve the SCNView
        let scnView = SCNView()
        scnView.scene = scene
        scnView.backgroundColor = UIColor.blue
        scnView.frame = CGRect(x: 0, y: 0, width: 500, height: 500)

        return scnView
    }

    func updateUIView(_ scnView: SCNView, context: Context) {
        print("test")

    }
}

0

如果你想让它看起来更加“性感”,你可以添加高光和灯光...然后你就得到了:

enter image description here

代码在此:

struct ScenekitView : UIViewRepresentable {

    let scene = SCNScene()


    func makeUIView(context: Context) -> SCNView {

        let uiView = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
        // create and add a camera to the scene
        let cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()

        let bezierPath = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 20, height: 20))

        let shape = SCNShape(path: bezierPath, extrusionDepth: 40)
        let shapeNode = SCNNode(geometry: shape)

        let material = SCNMaterial()
        material.diffuse.contents = UIColor.red
        material.specular.contents = UIColor.white

        let light = SCNLight()
        light.type = .spot
        cameraNode.light = light

        shape.materials = [material]

        shapeNode.rotation = SCNVector4(0.2, 0.3, 0.1, CGFloat.pi / 2)

        // place the camera
        cameraNode.position = SCNVector3(x: 5, y: 16, z: 85)

        scene.rootNode.addChildNode(cameraNode)
        scene.rootNode.addChildNode(shapeNode)

        // retrieve the SCNView
        let scnView = SCNView()
        scnView.scene = scene
        scnView.backgroundColor = UIColor.blue
        scnView.frame = CGRect(x: 0, y: 0, width: 400, height: 400)

        return scnView
    }

    func updateUIView(_ scnView: SCNView, context: Context) {
        print("test")

    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接